]> err.no Git - linux-2.6/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6
authorLinus Torvalds <torvalds@g5.osdl.org>
Wed, 4 Oct 2006 16:06:16 +0000 (09:06 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 4 Oct 2006 16:06:16 +0000 (09:06 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6: (292 commits)
  [GFS2] Fix endian bug for de_type
  [GFS2] Initialize SELinux extended attributes at inode creation time.
  [GFS2] Move logging code into log.c (mostly)
  [GFS2] Mark nlink cleared so VFS sees it happen
  [GFS2] Two redundant casts removed
  [GFS2] Remove uneeded endian conversion
  [GFS2] Remove duplicate sb reading code
  [GFS2] Mark metadata reads for blktrace
  [GFS2] Remove iflags.h, use FS_
  [GFS2] Fix code style/indent in ops_file.c
  [GFS2] streamline-generic_file_-interfaces-and-filemap gfs fix
  [GFS2] Remove readv/writev methods and use aio_read/aio_write instead (gfs bits)
  [GFS2] inode-diet: Eliminate i_blksize from the inode structure
  [GFS2] inode_diet: Replace inode.u.generic_ip with inode.i_private (gfs)
  [GFS2] Fix typo in last patch
  [GFS2] Fix direct i/o logic in filemap.c
  [GFS2] Fix bug in Makefiles for lock modules
  [GFS2] Remove (extra) fs_subsys declaration
  [GFS2/DLM] Fix trailing whitespace
  [GFS2] Tidy up meta_io code
  ...

1946 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/intel810.txt
Documentation/fb/intelfb.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/ia64/serial.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/kbuild/modules.txt
Documentation/kdump/kdump.txt
Documentation/kernel-docs.txt
Documentation/kernel-parameters.txt
Documentation/keys.txt
Documentation/kobject.txt
Documentation/kprobes.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/CARDLIST.cx88
Documentation/video4linux/CARDLIST.saa7134
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/entry.S
arch/alpha/kernel/head.S
arch/alpha/kernel/machvec_impl.h
arch/alpha/kernel/osf_sys.c
arch/alpha/kernel/srmcons.c
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/boot/compressed/head.S
arch/arm/common/sa1111.c
arch/arm/kernel/head.S
arch/arm/kernel/setup.c
arch/arm/kernel/smp.c
arch/arm/kernel/sys_arm.c
arch/arm/mach-ep93xx/edb9315a.c
arch/arm/mach-ep93xx/gesbc9312.c
arch/arm/mach-ep93xx/ts72xx.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-pnx4008/clock.c
arch/arm/mach-pxa/corgi_lcd.c
arch/arm/mach-pxa/generic.c
arch/arm/mach-pxa/idp.c
arch/arm/mach-pxa/leds.h
arch/arm/mach-pxa/lpd270.c
arch/arm/mach-pxa/lubbock.c
arch/arm/mach-pxa/mainstone.c
arch/arm/mach-pxa/poodle.c
arch/arm/mach-pxa/spitz.c
arch/arm/mach-pxa/trizeps4.c
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/mm/mmu.c
arch/arm/oprofile/op_model_xscale.c
arch/arm/plat-omap/sram-fn.S
arch/arm/vfp/vfpsingle.c
arch/arm26/kernel/setup.c
arch/arm26/kernel/sys_arm.c
arch/avr32/kernel/sys_avr32.c
arch/cris/arch-v10/drivers/Kconfig
arch/cris/arch-v32/Kconfig
arch/cris/arch-v32/kernel/smp.c
arch/cris/kernel/setup.c
arch/frv/Kconfig
arch/frv/kernel/Makefile
arch/frv/kernel/kernel_execve.S [new file with mode: 0644]
arch/frv/kernel/setup.c
arch/h8300/kernel/ints.c
arch/h8300/kernel/sys_h8300.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/kprobes.c
arch/i386/kernel/ldt.c
arch/i386/kernel/process.c
arch/i386/kernel/smpboot.c
arch/i386/kernel/sys_i386.c
arch/i386/kernel/traps.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/Kconfig
arch/ia64/hp/sim/simserial.c
arch/ia64/ia32/sys_ia32.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/kprobes.c
arch/ia64/kernel/msi_ia64.c [new file with mode: 0644]
arch/ia64/kernel/numa.c
arch/ia64/kernel/process.c
arch/ia64/kernel/setup.c
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/sn2/sn_hwperf.c
arch/ia64/sn/kernel/xpnet.c
arch/m32r/kernel/sys_m32r.c
arch/m68k/kernel/sys_m68k.c
arch/m68k/mm/motorola.c
arch/m68k/sun3/sun3dvma.c
arch/m68knommu/Kconfig
arch/m68knommu/kernel/sys_m68k.c
arch/m68knommu/platform/68328/head-pilot.S
arch/mips/Kconfig
arch/mips/Makefile
arch/mips/basler/excite/excite_flashtest.c [deleted file]
arch/mips/cobalt/setup.c
arch/mips/configs/atlas_defconfig
arch/mips/configs/bigsur_defconfig
arch/mips/configs/capcella_defconfig
arch/mips/configs/cobalt_defconfig
arch/mips/configs/db1000_defconfig
arch/mips/configs/db1100_defconfig
arch/mips/configs/db1200_defconfig
arch/mips/configs/db1500_defconfig
arch/mips/configs/db1550_defconfig
arch/mips/configs/ddb5477_defconfig
arch/mips/configs/decstation_defconfig
arch/mips/configs/e55_defconfig
arch/mips/configs/emma2rh_defconfig
arch/mips/configs/ev64120_defconfig
arch/mips/configs/excite_defconfig
arch/mips/configs/ip22_defconfig
arch/mips/configs/ip27_defconfig
arch/mips/configs/ip32_defconfig
arch/mips/configs/jaguar-atx_defconfig
arch/mips/configs/jmr3927_defconfig
arch/mips/configs/lasat200_defconfig
arch/mips/configs/malta_defconfig
arch/mips/configs/mipssim_defconfig
arch/mips/configs/mpc30x_defconfig
arch/mips/configs/ocelot_3_defconfig
arch/mips/configs/ocelot_c_defconfig
arch/mips/configs/ocelot_defconfig
arch/mips/configs/ocelot_g_defconfig
arch/mips/configs/pb1100_defconfig
arch/mips/configs/pb1500_defconfig
arch/mips/configs/pb1550_defconfig
arch/mips/configs/pnx8550-jbs_defconfig
arch/mips/configs/pnx8550-v2pci_defconfig
arch/mips/configs/qemu_defconfig
arch/mips/configs/rbhma4500_defconfig
arch/mips/configs/rm200_defconfig
arch/mips/configs/sb1250-swarm_defconfig
arch/mips/configs/sead_defconfig
arch/mips/configs/tb0226_defconfig
arch/mips/configs/tb0229_defconfig
arch/mips/configs/tb0287_defconfig
arch/mips/configs/workpad_defconfig
arch/mips/configs/wrppmc_defconfig
arch/mips/configs/yosemite_defconfig
arch/mips/dec/boot/Makefile [deleted file]
arch/mips/dec/boot/decstation.c [deleted file]
arch/mips/dec/boot/ld.ecoff [deleted file]
arch/mips/dec/prom/call_o32.S
arch/mips/dec/time.c
arch/mips/defconfig
arch/mips/ite-boards/Kconfig [deleted file]
arch/mips/ite-boards/generic/Makefile [deleted file]
arch/mips/ite-boards/generic/dbg_io.c [deleted file]
arch/mips/ite-boards/generic/irq.c [deleted file]
arch/mips/ite-boards/generic/it8172_cir.c [deleted file]
arch/mips/ite-boards/generic/it8172_setup.c [deleted file]
arch/mips/ite-boards/generic/lpc.c [deleted file]
arch/mips/ite-boards/generic/pmon_prom.c [deleted file]
arch/mips/ite-boards/generic/puts.c [deleted file]
arch/mips/ite-boards/generic/reset.c [deleted file]
arch/mips/ite-boards/generic/time.c [deleted file]
arch/mips/ite-boards/ivr/Makefile [deleted file]
arch/mips/ite-boards/ivr/README [deleted file]
arch/mips/ite-boards/ivr/init.c [deleted file]
arch/mips/ite-boards/qed-4n-s01b/Makefile [deleted file]
arch/mips/ite-boards/qed-4n-s01b/README [deleted file]
arch/mips/ite-boards/qed-4n-s01b/init.c [deleted file]
arch/mips/kernel/Makefile
arch/mips/kernel/genex.S
arch/mips/kernel/i8259.c
arch/mips/kernel/linux32.c
arch/mips/kernel/process.c
arch/mips/kernel/scall32-o32.S
arch/mips/kernel/scall64-64.S
arch/mips/kernel/scall64-n32.S
arch/mips/kernel/scall64-o32.S
arch/mips/kernel/signal_n32.c
arch/mips/kernel/stacktrace.c [new file with mode: 0644]
arch/mips/kernel/syscall.c
arch/mips/kernel/sysirix.c
arch/mips/kernel/time.c
arch/mips/kernel/traps.c
arch/mips/lasat/setup.c
arch/mips/mm/c-r3k.c
arch/mips/mm/c-r4k.c
arch/mips/mm/c-sb1.c
arch/mips/mm/c-tx39.c
arch/mips/mm/cache.c
arch/mips/mm/init.c
arch/mips/mm/tlbex-fault.S
arch/mips/mm/tlbex.c
arch/mips/pci/Makefile
arch/mips/pci/fixup-ite8172g.c [deleted file]
arch/mips/pci/fixup-ivr.c [deleted file]
arch/mips/pci/fixup-sb1250.c
arch/mips/pci/fixup-vr4133.c
arch/mips/pci/ops-it8172.c [deleted file]
arch/mips/sgi-ip22/ip22-reset.c
arch/mips/sgi-ip32/ip32-reset.c
arch/mips/sibyte/bcm1480/irq.c
arch/mips/sibyte/sb1250/irq.c
arch/mips/tx4938/common/irq.c
arch/parisc/Kconfig
arch/parisc/hpux/fs.c
arch/parisc/hpux/sys_hpux.c
arch/parisc/kernel/binfmt_elf32.c
arch/parisc/kernel/cache.c
arch/parisc/kernel/entry.S
arch/parisc/kernel/hardware.c
arch/parisc/kernel/irq.c
arch/parisc/kernel/process.c
arch/parisc/kernel/processor.c
arch/parisc/kernel/signal.c
arch/parisc/kernel/smp.c
arch/parisc/kernel/sys_parisc.c
arch/parisc/kernel/sys_parisc32.c
arch/parisc/kernel/syscall_table.S
arch/parisc/kernel/time.c
arch/parisc/kernel/traps.c
arch/parisc/mm/init.c
arch/parisc/mm/ioremap.c
arch/powerpc/Kconfig
arch/powerpc/Makefile
arch/powerpc/boot/Makefile
arch/powerpc/boot/dts/mpc8272ads.dts [new file with mode: 0644]
arch/powerpc/boot/dts/mpc8360emds.dts [new file with mode: 0644]
arch/powerpc/boot/dts/mpc8560ads.dts [new file with mode: 0644]
arch/powerpc/boot/wrapper [new file with mode: 0755]
arch/powerpc/boot/zImage.coff.lds.S [moved from arch/powerpc/boot/zImage.coff.lds with 96% similarity]
arch/powerpc/boot/zImage.lds.S [moved from arch/powerpc/boot/zImage.lds with 100% similarity]
arch/powerpc/configs/chrp32_defconfig
arch/powerpc/configs/g5_defconfig
arch/powerpc/configs/iseries_defconfig
arch/powerpc/configs/mpc7448_hpc2_defconfig
arch/powerpc/configs/mpc834x_itx_defconfig
arch/powerpc/configs/mpc8360emds_defconfig [new file with mode: 0644]
arch/powerpc/configs/mpc8560_ads_defconfig [moved from arch/mips/configs/ivr_defconfig with 58% similarity]
arch/powerpc/configs/pmac32_defconfig
arch/powerpc/configs/ppc64_defconfig
arch/powerpc/configs/pseries_defconfig
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/entry_64.S
arch/powerpc/kernel/head_64.S
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/kprobes.c
arch/powerpc/kernel/misc_32.S
arch/powerpc/kernel/misc_64.S
arch/powerpc/kernel/pci_64.c
arch/powerpc/kernel/perfmon_fsl_booke.c
arch/powerpc/kernel/process.c
arch/powerpc/kernel/ptrace.c
arch/powerpc/kernel/setup-common.c
arch/powerpc/kernel/setup_32.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/sys_ppc32.c
arch/powerpc/kernel/syscalls.c
arch/powerpc/kernel/sysfs.c
arch/powerpc/kernel/time.c
arch/powerpc/kernel/vmlinux.lds.S
arch/powerpc/lib/Makefile
arch/powerpc/lib/rheap.c
arch/powerpc/math-emu/Makefile
arch/powerpc/mm/pgtable_64.c
arch/powerpc/mm/slb_low.S
arch/powerpc/oprofile/backtrace.c
arch/powerpc/oprofile/op_model_7450.c
arch/powerpc/oprofile/op_model_fsl_booke.c
arch/powerpc/platforms/82xx/Kconfig [new file with mode: 0644]
arch/powerpc/platforms/82xx/Makefile [new file with mode: 0644]
arch/powerpc/platforms/82xx/m82xx_pci.h [new file with mode: 0644]
arch/powerpc/platforms/82xx/mpc82xx.c [new file with mode: 0644]
arch/powerpc/platforms/82xx/mpc82xx_ads.c [new file with mode: 0644]
arch/powerpc/platforms/82xx/pq2ads.h [new file with mode: 0644]
arch/powerpc/platforms/83xx/Kconfig
arch/powerpc/platforms/83xx/mpc832x_mds.c [new file with mode: 0644]
arch/powerpc/platforms/83xx/mpc832x_mds.h [new file with mode: 0644]
arch/powerpc/platforms/83xx/mpc834x_itx.c
arch/powerpc/platforms/83xx/mpc834x_sys.h
arch/powerpc/platforms/83xx/mpc8360e_pb.c [new file with mode: 0644]
arch/powerpc/platforms/85xx/Kconfig
arch/powerpc/platforms/85xx/Makefile
arch/powerpc/platforms/85xx/mpc8540_ads.h
arch/powerpc/platforms/85xx/mpc85xx.h
arch/powerpc/platforms/85xx/mpc85xx_ads.c
arch/powerpc/platforms/85xx/mpc85xx_ads.h [new file with mode: 0644]
arch/powerpc/platforms/85xx/mpc85xx_cds.h
arch/powerpc/platforms/cell/interrupt.c
arch/powerpc/platforms/cell/interrupt.h
arch/powerpc/platforms/cell/spider-pic.c
arch/powerpc/platforms/cell/spu_base.c
arch/powerpc/platforms/cell/spufs/file.c
arch/powerpc/platforms/cell/spufs/hw_ops.c
arch/powerpc/platforms/iseries/mf.c
arch/powerpc/platforms/iseries/pci.c
arch/powerpc/platforms/iseries/setup.c
arch/powerpc/platforms/maple/pci.c
arch/powerpc/platforms/powermac/udbg_scc.c
arch/powerpc/platforms/pseries/eeh.c
arch/powerpc/platforms/pseries/setup.c
arch/powerpc/sysdev/Makefile
arch/powerpc/sysdev/cpm2_common.c [new file with mode: 0644]
arch/powerpc/sysdev/cpm2_pic.c [new file with mode: 0644]
arch/powerpc/sysdev/cpm2_pic.h [new file with mode: 0644]
arch/powerpc/sysdev/fsl_soc.c
arch/powerpc/sysdev/fsl_soc.h
arch/powerpc/sysdev/ipic.c
arch/powerpc/sysdev/mpic.c
arch/powerpc/sysdev/qe_lib/Kconfig [new file with mode: 0644]
arch/powerpc/sysdev/qe_lib/Makefile [new file with mode: 0644]
arch/powerpc/sysdev/qe_lib/qe.c [new file with mode: 0644]
arch/powerpc/sysdev/qe_lib/qe_ic.c [new file with mode: 0644]
arch/powerpc/sysdev/qe_lib/qe_ic.h [new file with mode: 0644]
arch/powerpc/sysdev/qe_lib/qe_io.c [new file with mode: 0644]
arch/powerpc/sysdev/qe_lib/ucc.c [new file with mode: 0644]
arch/powerpc/sysdev/qe_lib/ucc_fast.c [new file with mode: 0644]
arch/powerpc/sysdev/qe_lib/ucc_slow.c [new file with mode: 0644]
arch/powerpc/xmon/xmon.c
arch/ppc/4xx_io/serial_sicc.c
arch/ppc/Kconfig
arch/ppc/boot/include/mpsc_defs.h
arch/ppc/boot/utils/mkbugboot.c
arch/ppc/boot/utils/mkprep.c
arch/ppc/kernel/misc.S
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/mpc866ads_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/s390/kernel/compat_linux.c
arch/s390/kernel/kprobes.c
arch/s390/kernel/sys_s390.c
arch/sh/Kconfig
arch/sh/boards/bigsur/io.c
arch/sh/boards/bigsur/led.c
arch/sh/boards/ec3104/io.c
arch/sh/boards/hp6xx/hp6xx_apm.c
arch/sh/boards/hp6xx/pm.c
arch/sh/boards/hp6xx/setup.c
arch/sh/boards/landisk/irq.c
arch/sh/boards/landisk/landisk_pwb.c
arch/sh/boards/landisk/rtc.c
arch/sh/boards/landisk/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/r7780rp/irq.c
arch/sh/boards/renesas/r7780rp/led.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/7343/io.c
arch/sh/boards/se/7343/irq.c
arch/sh/boards/se/7343/led.c
arch/sh/boards/se/7343/setup.c
arch/sh/boards/se/770x/led.c
arch/sh/boards/se/770x/setup.c
arch/sh/boards/se/7751/led.c
arch/sh/boards/se/7751/pci.c
arch/sh/boards/se/7751/setup.c
arch/sh/boards/sh03/setup.c
arch/sh/boards/superh/microdev/io.c
arch/sh/boards/superh/microdev/led.c
arch/sh/boot/.gitignore [new file with mode: 0644]
arch/sh/configs/adx_defconfig [deleted file]
arch/sh/configs/cqreek_defconfig [deleted file]
arch/sh/configs/dreamcast_defconfig
arch/sh/configs/hp6xx_defconfig
arch/sh/configs/hs7751rvoip_defconfig [moved from arch/mips/configs/it8172_defconfig with 53% similarity]
arch/sh/configs/landisk_defconfig
arch/sh/configs/microdev_defconfig
arch/sh/configs/r7780rp_defconfig
arch/sh/configs/rts7751r2d_defconfig
arch/sh/configs/se7300_defconfig
arch/sh/configs/se73180_defconfig
arch/sh/configs/se7343_defconfig
arch/sh/configs/se7705_defconfig
arch/sh/configs/se7750_defconfig
arch/sh/configs/se7751_defconfig
arch/sh/configs/sh03_defconfig
arch/sh/configs/sh7710voipgw_defconfig
arch/sh/configs/shmin_defconfig
arch/sh/configs/snapgear_defconfig
arch/sh/configs/systemh_defconfig
arch/sh/configs/titan_defconfig
arch/sh/drivers/dma/dma-pvr2.c
arch/sh/drivers/dma/dma-sysfs.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-landisk.c
arch/sh/drivers/pci/ops-r7780rp.c
arch/sh/drivers/pci/ops-rts7751r2d.c
arch/sh/drivers/pci/ops-sh03.c
arch/sh/drivers/pci/ops-titan.c
arch/sh/drivers/pci/pci-sh7780.c
arch/sh/kernel/apm.c
arch/sh/kernel/cpu/ubc.S
arch/sh/kernel/entry.S
arch/sh/kernel/setup.c
arch/sh/kernel/sh_ksyms.c
arch/sh/kernel/smp.c
arch/sh/kernel/sys_sh.c
arch/sh/kernel/vsyscall/.gitignore [new file with mode: 0644]
arch/sh/math-emu/math.c
arch/sh/mm/cache-debugfs.c
arch/sh/tools/gen-mach-types
arch/sh64/boot/compressed/misc.c
arch/sh64/configs/cayman_defconfig
arch/sh64/kernel/alphanum.c
arch/sh64/kernel/process.c
arch/sh64/kernel/sys_sh64.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/sparc/kernel/sys_sparc.c
arch/sparc/kernel/sys_sunos.c
arch/sparc64/Kconfig
arch/sparc64/defconfig
arch/sparc64/kernel/power.c
arch/sparc64/kernel/signal32.c
arch/sparc64/kernel/sys_sparc.c
arch/sparc64/kernel/sys_sparc32.c
arch/sparc64/kernel/sys_sunos32.c
arch/sparc64/solaris/fs.c
arch/sparc64/solaris/misc.c
arch/um/Kconfig
arch/um/Makefile
arch/um/drivers/line.c
arch/um/drivers/mconsole_kern.c
arch/um/include/line.h
arch/um/include/sysdep-x86_64/ptrace_user.h
arch/um/kernel/syscall.c
arch/um/kernel/um_arch.c
arch/um/os-Linux/process.c
arch/um/os-Linux/sys-i386/tls.c
arch/um/os-Linux/tls.c
arch/um/sys-i386/unmap.c
arch/um/sys-x86_64/syscalls.c
arch/um/sys-x86_64/sysrq.c
arch/um/sys-x86_64/unmap.c
arch/v850/kernel/entry.S
arch/v850/kernel/memcons.c
arch/v850/kernel/simcons.c
arch/v850/kernel/syscalls.c
arch/x86_64/Kconfig
arch/x86_64/ia32/sys_ia32.c
arch/x86_64/kernel/apic.c
arch/x86_64/kernel/entry.S
arch/x86_64/kernel/i8259.c
arch/x86_64/kernel/io_apic.c
arch/x86_64/kernel/irq.c
arch/x86_64/kernel/kprobes.c
arch/x86_64/kernel/mpparse.c
arch/x86_64/kernel/process.c
arch/x86_64/kernel/sys_x86_64.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
arch/xtensa/platform-iss/console.c
block/ioctl.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/atm/adummy.c
drivers/atm/ambassador.c
drivers/atm/firestream.c
drivers/atm/he.c
drivers/atm/horizon.c
drivers/atm/idt77252.c
drivers/atm/lanai.c
drivers/atm/zatm.c
drivers/block/Kconfig
drivers/block/pktcdvd.c
drivers/block/swim3.c
drivers/block/umem.c
drivers/cdrom/cdrom.c
drivers/char/.gitignore
drivers/char/Kconfig
drivers/char/Makefile
drivers/char/agp/Kconfig
drivers/char/agp/Makefile
drivers/char/agp/parisc-agp.c [new file with mode: 0644]
drivers/char/amiserial.c
drivers/char/cyclades.c
drivers/char/epca.c
drivers/char/epca.h
drivers/char/esp.c
drivers/char/generic_serial.c
drivers/char/hvc_console.c
drivers/char/hvc_iseries.c
drivers/char/hvc_vio.c
drivers/char/hvcs.c
drivers/char/hvsi.c
drivers/char/hw_random/ixp4xx-rng.c
drivers/char/hw_random/omap-rng.c
drivers/char/ip2/ip2main.c
drivers/char/ipmi/ipmi_si_intf.c
drivers/char/isicom.c
drivers/char/istallion.c
drivers/char/ite_gpio.c [deleted file]
drivers/char/keyboard.c
drivers/char/moxa.c
drivers/char/mwave/README
drivers/char/mxser.c
drivers/char/nwbutton.c
drivers/char/pcmcia/synclink_cs.c
drivers/char/pty.c
drivers/char/qtronixmap.c_shipped [deleted file]
drivers/char/qtronixmap.map [deleted file]
drivers/char/random.c
drivers/char/rio/rio_linux.c
drivers/char/riscom8.c
drivers/char/rocket.c
drivers/char/ser_a2232.c
drivers/char/serial167.c
drivers/char/snsc_event.c
drivers/char/specialix.c
drivers/char/stallion.c
drivers/char/sx.c
drivers/char/synclink.c
drivers/char/synclink_gt.c
drivers/char/synclinkmp.c
drivers/char/tipar.c
drivers/char/tty_io.c
drivers/char/viocons.c
drivers/char/vme_scc.c
drivers/char/vt.c
drivers/char/vt_ioctl.c
drivers/char/watchdog/Kconfig
drivers/char/watchdog/Makefile
drivers/char/watchdog/acquirewdt.c
drivers/char/watchdog/advantechwdt.c
drivers/char/watchdog/alim1535_wdt.c
drivers/char/watchdog/alim7101_wdt.c
drivers/char/watchdog/at91_wdt.c
drivers/char/watchdog/booke_wdt.c
drivers/char/watchdog/cpu5wdt.c
drivers/char/watchdog/ep93xx_wdt.c
drivers/char/watchdog/eurotechwdt.c
drivers/char/watchdog/i6300esb.c
drivers/char/watchdog/i8xx_tco.c
drivers/char/watchdog/iTCO_wdt.c [new file with mode: 0644]
drivers/char/watchdog/ib700wdt.c
drivers/char/watchdog/ibmasr.c
drivers/char/watchdog/indydog.c
drivers/char/watchdog/ixp2000_wdt.c
drivers/char/watchdog/ixp4xx_wdt.c
drivers/char/watchdog/machzwd.c
drivers/char/watchdog/mixcomwd.c
drivers/char/watchdog/mpc83xx_wdt.c
drivers/char/watchdog/mpc8xx_wdt.c
drivers/char/watchdog/mpcore_wdt.c
drivers/char/watchdog/mv64x60_wdt.c
drivers/char/watchdog/pcwd.c
drivers/char/watchdog/pcwd_pci.c
drivers/char/watchdog/pcwd_usb.c
drivers/char/watchdog/pnx4008_wdt.c [new file with mode: 0644]
drivers/char/watchdog/s3c2410_wdt.c
drivers/char/watchdog/sa1100_wdt.c
drivers/char/watchdog/sbc60xxwdt.c
drivers/char/watchdog/sbc_epx_c3.c
drivers/char/watchdog/sc1200wdt.c
drivers/char/watchdog/sc520_wdt.c
drivers/char/watchdog/scx200_wdt.c
drivers/char/watchdog/shwdt.c
drivers/char/watchdog/softdog.c
drivers/char/watchdog/w83627hf_wdt.c
drivers/char/watchdog/w83877f_wdt.c
drivers/char/watchdog/w83977f_wdt.c
drivers/char/watchdog/wafer5823wdt.c
drivers/char/watchdog/wdrtas.c
drivers/char/watchdog/wdt.c
drivers/char/watchdog/wdt285.c
drivers/char/watchdog/wdt977.c
drivers/char/watchdog/wdt_pci.c
drivers/clocksource/scx200_hrt.c
drivers/cpufreq/cpufreq.c
drivers/firmware/Kconfig
drivers/firmware/dell_rbu.c
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/Kconfig
drivers/ide/h8300/ide-h8300.c
drivers/ide/ide-dma.c
drivers/ide/ide-io.c
drivers/ide/ide-iops.c
drivers/ide/ide-lib.c
drivers/ide/ide-probe.c
drivers/ide/ide-proc.c
drivers/ide/ide.c
drivers/ide/legacy/ide-cs.c
drivers/ide/pci/Makefile
drivers/ide/pci/cs5530.c
drivers/ide/pci/cy82c693.c
drivers/ide/pci/generic.c
drivers/ide/pci/it8172.c [deleted file]
drivers/ide/pci/jmicron.c [new file with mode: 0644]
drivers/ide/pci/pdc202xx_old.c
drivers/ide/pci/piix.c
drivers/ide/pci/sc1200.c
drivers/ide/pci/sgiioc4.c
drivers/ide/pci/siimage.c
drivers/ide/pci/via82cxxx.c
drivers/ide/ppc/pmac.c
drivers/ide/setup-pci.c
drivers/ieee1394/Kconfig
drivers/infiniband/core/cma.c
drivers/infiniband/hw/ehca/ehca_main.c
drivers/infiniband/hw/ehca/ehca_tools.h
drivers/infiniband/hw/ipath/ipath_rc.c
drivers/infiniband/hw/ipath/ipath_verbs.c
drivers/infiniband/ulp/ipoib/Kconfig
drivers/input/Kconfig
drivers/input/Makefile
drivers/input/evbug.c
drivers/input/evdev.c
drivers/input/ff-core.c [new file with mode: 0644]
drivers/input/ff-memless.c [new file with mode: 0644]
drivers/input/fixp-arith.h [moved from drivers/usb/input/fixp-arith.h with 100% similarity]
drivers/input/input.c
drivers/input/joydev.c
drivers/input/joystick/Kconfig
drivers/input/joystick/iforce/iforce-ff.c
drivers/input/joystick/iforce/iforce-main.c
drivers/input/joystick/iforce/iforce-packets.c
drivers/input/joystick/iforce/iforce.h
drivers/input/keyboard/Kconfig
drivers/input/keyboard/Makefile
drivers/input/keyboard/atkbd.c
drivers/input/keyboard/stowaway.c [new file with mode: 0644]
drivers/input/misc/uinput.c
drivers/input/misc/wistron_btns.c
drivers/input/mouse/alps.c
drivers/input/mouse/alps.h
drivers/input/mouse/lifebook.c
drivers/input/mouse/logips2pp.c
drivers/input/mouse/psmouse-base.c
drivers/input/mouse/sermouse.c
drivers/input/mouse/synaptics.c
drivers/input/mousedev.c
drivers/input/power.c
drivers/input/serio/Kconfig
drivers/input/serio/i8042-x86ia64io.h
drivers/input/serio/i8042.c
drivers/input/serio/i8042.h
drivers/input/serio/libps2.c
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/Makefile
drivers/input/touchscreen/elo.c
drivers/input/touchscreen/penmount.c [new file with mode: 0644]
drivers/input/touchscreen/touchright.c [new file with mode: 0644]
drivers/input/touchscreen/touchwin.c [new file with mode: 0644]
drivers/input/tsdev.c
drivers/isdn/capi/capi.c
drivers/isdn/gigaset/interface.c
drivers/isdn/gigaset/proc.c
drivers/isdn/hardware/eicon/Kconfig
drivers/isdn/hisax/Kconfig
drivers/isdn/hisax/amd7930_fn.h
drivers/isdn/hisax/config.c
drivers/isdn/hisax/hfc4s8s_l1.c
drivers/isdn/hisax/hfc_sx.c
drivers/isdn/hisax/hfc_usb.c
drivers/isdn/hisax/hisax.h
drivers/isdn/hisax/hisax_fcpcipnp.c
drivers/isdn/hisax/niccy.c
drivers/isdn/hisax/st5481_b.c
drivers/isdn/hisax/st5481_d.c
drivers/isdn/i4l/isdn_tty.c
drivers/isdn/sc/command.c
drivers/isdn/sc/event.c
drivers/isdn/sc/interrupt.c
drivers/isdn/sc/timer.c
drivers/leds/led-class.c
drivers/leds/leds-locomo.c
drivers/macintosh/Kconfig
drivers/macintosh/adbhid.c
drivers/macintosh/via-pmu.c
drivers/md/Kconfig
drivers/md/bitmap.c
drivers/md/dm-crypt.c
drivers/md/dm-exception-store.c
drivers/md/dm-linear.c
drivers/md/dm-mpath.c
drivers/md/dm-raid1.c
drivers/md/dm-snap.c
drivers/md/dm-snap.h
drivers/md/dm-table.c
drivers/md/dm.c
drivers/md/dm.h
drivers/md/linear.c
drivers/md/md.c
drivers/md/multipath.c
drivers/md/raid0.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid5.c
drivers/media/dvb/cinergyT2/Kconfig
drivers/media/dvb/dvb-core/dvb_frontend.c
drivers/media/dvb/dvb-core/dvb_frontend.h
drivers/media/dvb/dvb-core/dvb_ringbuffer.c
drivers/media/dvb/dvb-usb/Kconfig
drivers/media/dvb/dvb-usb/Makefile
drivers/media/dvb/dvb-usb/a800.c
drivers/media/dvb/dvb-usb/cxusb.c
drivers/media/dvb/dvb-usb/dib0700.h [new file with mode: 0644]
drivers/media/dvb/dvb-usb/dib0700_core.c [new file with mode: 0644]
drivers/media/dvb/dvb-usb/dib0700_devices.c [new file with mode: 0644]
drivers/media/dvb/dvb-usb/dib07x0.h [new file with mode: 0644]
drivers/media/dvb/dvb-usb/dibusb-common.c
drivers/media/dvb/dvb-usb/dibusb-mb.c
drivers/media/dvb/dvb-usb/dibusb-mc.c
drivers/media/dvb/dvb-usb/dibusb.h
drivers/media/dvb/dvb-usb/digitv.c
drivers/media/dvb/dvb-usb/dtt200u.c
drivers/media/dvb/dvb-usb/dvb-usb-common.h
drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
drivers/media/dvb/dvb-usb/dvb-usb-ids.h
drivers/media/dvb/dvb-usb/dvb-usb-init.c
drivers/media/dvb/dvb-usb/dvb-usb-remote.c
drivers/media/dvb/dvb-usb/dvb-usb-urb.c
drivers/media/dvb/dvb-usb/dvb-usb.h
drivers/media/dvb/dvb-usb/gp8psk.c
drivers/media/dvb/dvb-usb/nova-t-usb2.c
drivers/media/dvb/dvb-usb/umt-010.c
drivers/media/dvb/dvb-usb/usb-urb.c [new file with mode: 0644]
drivers/media/dvb/dvb-usb/vp702x-fe.c
drivers/media/dvb/dvb-usb/vp702x.c
drivers/media/dvb/dvb-usb/vp702x.h
drivers/media/dvb/dvb-usb/vp7045.c
drivers/media/dvb/frontends/cx24123.c
drivers/media/dvb/frontends/dib3000mc.c
drivers/media/dvb/frontends/dib3000mc.h
drivers/media/dvb/frontends/mt2060.c
drivers/media/dvb/frontends/mt2060.h
drivers/media/radio/Kconfig
drivers/media/video/Kconfig
drivers/media/video/bt8xx/bttv-cards.c
drivers/media/video/cx88/Kconfig
drivers/media/video/cx88/cx88-blackbird.c
drivers/media/video/cx88/cx88-cards.c
drivers/media/video/cx88/cx88-core.c
drivers/media/video/cx88/cx88-dvb.c
drivers/media/video/cx88/cx88-i2c.c
drivers/media/video/cx88/cx88-mpeg.c
drivers/media/video/cx88/cx88-tvaudio.c
drivers/media/video/cx88/cx88-video.c
drivers/media/video/cx88/cx88.h
drivers/media/video/ir-kbd-i2c.c
drivers/media/video/msp3400-driver.c
drivers/media/video/msp3400-driver.h
drivers/media/video/msp3400-kthreads.c
drivers/media/video/pvrusb2/Kconfig
drivers/media/video/pvrusb2/pvrusb2-hdw.c
drivers/media/video/pvrusb2/pvrusb2-hdw.h
drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
drivers/media/video/pvrusb2/pvrusb2-v4l2.c
drivers/media/video/pwc/philips.txt
drivers/media/video/saa7134/saa7134-cards.c
drivers/media/video/saa7134/saa7134-dvb.c
drivers/media/video/saa7134/saa7134-input.c
drivers/media/video/saa7134/saa7134.h
drivers/media/video/video-buf.c
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/lkdtm.c [new file with mode: 0644]
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/arctic-mtd.c
drivers/mtd/maps/bast-flash.c
drivers/mtd/maps/beech-mtd.c
drivers/mtd/maps/cstm_mips_ixx.c
drivers/mtd/maps/dmv182.c
drivers/mtd/maps/nettel.c
drivers/mtd/maps/redwood.c
drivers/mtd/mtd_blkdevs.c
drivers/mtd/nand/Kconfig
drivers/mtd/nand/edb7312.c
drivers/mtd/nand/nand_base.c
drivers/mtd/nand/nand_bbt.c
drivers/mtd/nftlcore.c
drivers/mtd/onenand/Kconfig
drivers/mtd/onenand/onenand_base.c
drivers/net/Kconfig
drivers/net/Space.c
drivers/net/arm/am79c961a.h
drivers/net/e100.c
drivers/net/e1000/LICENSE [deleted file]
drivers/net/e1000/Makefile
drivers/net/e1000/e1000.h
drivers/net/e1000/e1000_ethtool.c
drivers/net/e1000/e1000_hw.c
drivers/net/e1000/e1000_hw.h
drivers/net/e1000/e1000_main.c
drivers/net/e1000/e1000_osdep.h
drivers/net/e1000/e1000_param.c
drivers/net/fs_enet/fs_enet-main.c
drivers/net/hp100.c
drivers/net/ibm_emac/ibm_emac_debug.h
drivers/net/ibm_emac/ibm_emac_rgmii.h
drivers/net/ifb.c
drivers/net/ixgb/Makefile
drivers/net/ixgb/ixgb.h
drivers/net/ixgb/ixgb_ee.c
drivers/net/ixgb/ixgb_ee.h
drivers/net/ixgb/ixgb_ethtool.c
drivers/net/ixgb/ixgb_hw.c
drivers/net/ixgb/ixgb_hw.h
drivers/net/ixgb/ixgb_ids.h
drivers/net/ixgb/ixgb_main.c
drivers/net/ixgb/ixgb_osdep.h
drivers/net/ixgb/ixgb_param.c
drivers/net/phy/fixed.c
drivers/net/phy/phy_device.c
drivers/net/sky2.c
drivers/net/sky2.h
drivers/net/spider_net.c
drivers/net/tokenring/tmspci.c
drivers/net/tun.c
drivers/net/wireless/Kconfig
drivers/net/wireless/airo.c
drivers/net/wireless/ipw2100.c
drivers/parisc/iosapic.c
drivers/parisc/lba_pci.c
drivers/parisc/led.c
drivers/parisc/power.c
drivers/parisc/sba_iommu.c
drivers/parport/daisy.c
drivers/parport/parport_pc.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/pnp/isapnp/core.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/s390/char/con3215.c
drivers/s390/char/fs3270.c
drivers/s390/char/sclp_tty.c
drivers/s390/char/sclp_vt220.c
drivers/s390/char/tty3270.c
drivers/s390/s390mach.c
drivers/sbus/char/aurora.c
drivers/sbus/char/bbc_envctrl.c
drivers/sbus/char/cpwatchdog.c
drivers/sbus/char/envctrl.c
drivers/scsi/Kconfig
drivers/scsi/aic7xxx/Kconfig.aic79xx
drivers/scsi/aic7xxx/Kconfig.aic7xxx
drivers/scsi/arm/arxescsi.c
drivers/scsi/lpfc/lpfc_ct.c
drivers/serial/21285.c
drivers/serial/68328serial.c
drivers/serial/68360serial.c
drivers/serial/8250.c
drivers/serial/8250_gsc.c
drivers/serial/8250_pci.c
drivers/serial/8250_pnp.c
drivers/serial/Kconfig
drivers/serial/cpm_uart/cpm_uart_core.c
drivers/serial/cpm_uart/cpm_uart_cpm1.h
drivers/serial/cpm_uart/cpm_uart_cpm2.c
drivers/serial/cpm_uart/cpm_uart_cpm2.h
drivers/serial/crisv10.c
drivers/serial/m32r_sio.c
drivers/serial/mcfserial.c
drivers/serial/serial_core.c
drivers/serial/serial_cs.c
drivers/serial/serial_txx9.c
drivers/tc/zs.c
drivers/usb/atm/Kconfig
drivers/usb/class/cdc-acm.c
drivers/usb/core/devio.c
drivers/usb/core/file.c
drivers/usb/core/hcd.c
drivers/usb/core/inode.c
drivers/usb/core/usb.c
drivers/usb/core/usb.h
drivers/usb/gadget/Kconfig
drivers/usb/gadget/ether.c
drivers/usb/gadget/file_storage.c
drivers/usb/gadget/gmidi.c
drivers/usb/gadget/serial.c
drivers/usb/gadget/zero.c
drivers/usb/input/Kconfig
drivers/usb/input/Makefile
drivers/usb/input/hid-core.c
drivers/usb/input/hid-ff.c
drivers/usb/input/hid-input.c
drivers/usb/input/hid-lgff.c
drivers/usb/input/hid-pidff.c [new file with mode: 0644]
drivers/usb/input/hid-tmff.c
drivers/usb/input/hid-zpff.c [new file with mode: 0644]
drivers/usb/input/hid.h
drivers/usb/input/pid.c [deleted file]
drivers/usb/input/pid.h [deleted file]
drivers/usb/serial/usb-serial.c
drivers/usb/storage/Kconfig
drivers/video/Kconfig
drivers/video/Makefile
drivers/video/aty/atyfb.h
drivers/video/aty/atyfb_base.c
drivers/video/aty/mach64_ct.c
drivers/video/aty/radeon_i2c.c
drivers/video/aty/radeon_pm.c
drivers/video/au1100fb.c
drivers/video/console/fbcon.c
drivers/video/console/fbcon.h
drivers/video/console/fbcon_ccw.c
drivers/video/console/fbcon_cw.c
drivers/video/console/fbcon_ud.c
drivers/video/console/softcursor.c
drivers/video/fb_ddc.c [new file with mode: 0644]
drivers/video/fbmem.c
drivers/video/fbsysfs.c
drivers/video/i810/i810-i2c.c
drivers/video/i810/i810_main.c
drivers/video/matrox/matroxfb_base.c
drivers/video/mbx/mbxfb.c
drivers/video/nvidia/nv_i2c.c
drivers/video/nvidia/nvidia.c
drivers/video/pxafb.c
drivers/video/pxafb.h
drivers/video/riva/fbdev.c
drivers/video/riva/rivafb-i2c.c
drivers/video/s3c2410fb.h
drivers/video/savage/savagefb-i2c.c
drivers/video/sis/init.h
drivers/video/sis/init301.h
drivers/video/sis/initextlfb.c
drivers/video/sis/osdef.h
drivers/video/sis/sis_accel.c
drivers/video/sis/sis_accel.h
drivers/video/sis/sis_main.c
drivers/video/sis/sis_main.h
drivers/video/sis/vgatypes.h
drivers/video/sstfb.c
drivers/w1/Kconfig
fs/Kconfig
fs/Makefile
fs/afs/dir.c
fs/aio.c
fs/befs/befs_fs_types.h
fs/binfmt_som.c
fs/cifs/README
fs/cifs/connect.c
fs/cifs/sess.c
fs/compat.c
fs/configfs/file.c
fs/dcache.c
fs/debugfs/inode.c
fs/dnotify.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/eventpoll.c
fs/exec.c
fs/exportfs/expfs.c
fs/fat/dir.c
fs/fcntl.c
fs/file_table.c
fs/hfsplus/part_tbl.c
fs/inode.c
fs/jbd/commit.c
fs/jbd/journal.c
fs/jfs/acl.c
fs/jfs/endian24.h
fs/jfs/file.c
fs/jfs/inode.c
fs/jfs/jfs_acl.h
fs/jfs/jfs_btree.h
fs/jfs/jfs_debug.c
fs/jfs/jfs_dinode.h
fs/jfs/jfs_dmap.c
fs/jfs/jfs_dmap.h
fs/jfs/jfs_dtree.c
fs/jfs/jfs_dtree.h
fs/jfs/jfs_extent.c
fs/jfs/jfs_extent.h
fs/jfs/jfs_filsys.h
fs/jfs/jfs_imap.c
fs/jfs/jfs_imap.h
fs/jfs/jfs_incore.h
fs/jfs/jfs_inode.c
fs/jfs/jfs_inode.h
fs/jfs/jfs_lock.h
fs/jfs/jfs_logmgr.c
fs/jfs/jfs_logmgr.h
fs/jfs/jfs_metapage.c
fs/jfs/jfs_metapage.h
fs/jfs/jfs_mount.c
fs/jfs/jfs_superblock.h
fs/jfs/jfs_txnmgr.c
fs/jfs/jfs_txnmgr.h
fs/jfs/jfs_umount.c
fs/jfs/jfs_unicode.c
fs/jfs/jfs_unicode.h
fs/jfs/jfs_uniupr.c
fs/jfs/jfs_xattr.h
fs/jfs/jfs_xtree.c
fs/jfs/jfs_xtree.h
fs/jfs/namei.c
fs/jfs/resize.c
fs/jfs/super.c
fs/jfs/symlink.c
fs/jfs/xattr.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/lockd/xdr.c
fs/locks.c
fs/namespace.c
fs/nfs/callback.c
fs/nfs/client.c
fs/nfs/nfsroot.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/nfs4callback.c
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4recover.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/proc/array.c
fs/proc/base.c
fs/proc/proc_misc.c
fs/proc/root.c
fs/readdir.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/reiserfs/xattr.c
fs/stat.c
fs/sysfs/file.c
fs/xfs/support/debug.c
include/asm-alpha/unistd.h
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/clock.h
include/asm-arm/arch-pnx4008/platform.h
include/asm-arm/arch-pxa/pxafb.h
include/asm-arm/arch-pxa/spitz.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-arm/timeofday.h [deleted file]
include/asm-arm/unistd.h
include/asm-arm26/assembler.h
include/asm-arm26/namei.h
include/asm-arm26/semaphore.h
include/asm-arm26/unistd.h
include/asm-avr32/unistd.h
include/asm-cris/unistd.h
include/asm-frv/namei.h
include/asm-frv/unistd.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-h8300/unistd.h
include/asm-i386/bugs.h
include/asm-i386/elf.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/mca_dma.h
include/asm-i386/msi.h [deleted file]
include/asm-i386/msidef.h [new file with mode: 0644]
include/asm-i386/ptrace.h
include/asm-i386/topology.h
include/asm-i386/unistd.h
include/asm-ia64/machvec.h
include/asm-ia64/machvec_sn2.h
include/asm-ia64/msi.h [deleted file]
include/asm-ia64/ptrace.h
include/asm-ia64/topology.h
include/asm-ia64/unistd.h
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-m32r/unistd.h
include/asm-m68k/rtc.h
include/asm-m68k/unistd.h
include/asm-m68knommu/processor.h
include/asm-m68knommu/unistd.h
include/asm-mips/bootinfo.h
include/asm-mips/cacheflush.h
include/asm-mips/galileo-boards/ev96100.h [deleted file]
include/asm-mips/galileo-boards/ev96100int.h [deleted file]
include/asm-mips/irqflags.h
include/asm-mips/it8172/it8172.h [deleted file]
include/asm-mips/it8172/it8172_cir.h [deleted file]
include/asm-mips/it8172/it8172_dbg.h [deleted file]
include/asm-mips/it8172/it8172_int.h [deleted file]
include/asm-mips/it8172/it8172_pci.h [deleted file]
include/asm-mips/it8712.h [deleted file]
include/asm-mips/mach-ev64120/mach-gt64120.h
include/asm-mips/mach-ip27/topology.h
include/asm-mips/ptrace.h
include/asm-mips/serial.h
include/asm-mips/stacktrace.h [new file with mode: 0644]
include/asm-mips/tx4938/tx4938_mips.h
include/asm-mips/unistd.h
include/asm-parisc/agp.h [new file with mode: 0644]
include/asm-parisc/assembly.h
include/asm-parisc/cacheflush.h
include/asm-parisc/compat.h
include/asm-parisc/dma.h
include/asm-parisc/futex.h
include/asm-parisc/io.h
include/asm-parisc/iosapic.h [deleted file]
include/asm-parisc/irq.h
include/asm-parisc/mckinley.h [new file with mode: 0644]
include/asm-parisc/page.h
include/asm-parisc/param.h
include/asm-parisc/parisc-device.h
include/asm-parisc/pci.h
include/asm-parisc/prefetch.h [new file with mode: 0644]
include/asm-parisc/processor.h
include/asm-parisc/ropes.h [new file with mode: 0644]
include/asm-parisc/rtc.h
include/asm-parisc/serial.h
include/asm-parisc/spinlock.h
include/asm-parisc/unistd.h
include/asm-powerpc/firmware.h
include/asm-powerpc/fs_pd.h [new file with mode: 0644]
include/asm-powerpc/immap_qe.h [new file with mode: 0644]
include/asm-powerpc/io.h
include/asm-powerpc/ipic.h
include/asm-powerpc/kprobes.h
include/asm-powerpc/mpc85xx.h [new file with mode: 0644]
include/asm-powerpc/ptrace.h
include/asm-powerpc/qe.h [new file with mode: 0644]
include/asm-powerpc/qe_ic.h [new file with mode: 0644]
include/asm-powerpc/system.h
include/asm-powerpc/time.h
include/asm-powerpc/topology.h
include/asm-powerpc/ucc.h [new file with mode: 0644]
include/asm-powerpc/ucc_fast.h [new file with mode: 0644]
include/asm-powerpc/ucc_slow.h [new file with mode: 0644]
include/asm-powerpc/unistd.h
include/asm-powerpc/xmon.h
include/asm-ppc/cpm2.h
include/asm-ppc/fs_pd.h [new file with mode: 0644]
include/asm-ppc/mv64x60_defs.h
include/asm-ppc/rheap.h
include/asm-ppc/rtc.h
include/asm-s390/ptrace.h
include/asm-s390/qdio.h
include/asm-s390/unistd.h
include/asm-sh/.gitignore [new file with mode: 0644]
include/asm-sh/bigsur/io.h
include/asm-sh/bigsur/serial.h
include/asm-sh/bugs.h
include/asm-sh/cpu-sh3/rtc.h [deleted file]
include/asm-sh/cpu-sh4/rtc.h [deleted file]
include/asm-sh/dreamcast/sysasic.h
include/asm-sh/elf.h
include/asm-sh/hd64465/io.h
include/asm-sh/hs7751rvoip/io.h [deleted file]
include/asm-sh/mpc1211/io.h
include/asm-sh/rts7751r2d/io.h [deleted file]
include/asm-sh/rts7751r2d/rts7751r2d.h
include/asm-sh/sfp-machine.h
include/asm-sh/spinlock.h
include/asm-sh/string.h
include/asm-sh/unistd.h
include/asm-sh64/serial.h
include/asm-sh64/unistd.h
include/asm-sparc/reg.h
include/asm-sparc/unistd.h
include/asm-sparc64/compat_signal.h [new file with mode: 0644]
include/asm-sparc64/signal.h
include/asm-sparc64/unistd.h
include/asm-um/unistd.h
include/asm-v850/unistd.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-x86_64/ptrace.h
include/asm-x86_64/topology.h
include/asm-x86_64/unistd.h
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/asm-xtensa/unistd.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/compat.h
include/linux/compat_ioctl.h
include/linux/console.h
include/linux/console_struct.h
include/linux/consolemap.h
include/linux/debug_locks.h
include/linux/device-mapper.h
include/linux/dm-ioctl.h
include/linux/fb.h
include/linux/fs.h
include/linux/fs_enet_pd.h
include/linux/fs_uart_pd.h
include/linux/fsl_devices.h
include/linux/genalloc.h
include/linux/hardirq.h
include/linux/harrier_defs.h
include/linux/htirq.h [new file with mode: 0644]
include/linux/ide.h
include/linux/in.h
include/linux/init_task.h
include/linux/input.h
include/linux/ip.h
include/linux/ipc.h
include/linux/ipsec.h
include/linux/irq.h
include/linux/ite_gpio.h [deleted file]
include/linux/kallsyms.h
include/linux/kernel.h
include/linux/kprobes.h
include/linux/libata.h
include/linux/libps2.h
include/linux/lockd/bind.h
include/linux/lockd/lockd.h
include/linux/lockd/share.h
include/linux/lockd/sm_inter.h
include/linux/lockd/xdr4.h
include/linux/module.h
include/linux/msi.h [new file with mode: 0644]
include/linux/mtd/nand.h
include/linux/mtd/onenand.h
include/linux/mtd/onenand_regs.h
include/linux/mtd/plat-ram.h
include/linux/namespace.h
include/linux/netfilter_bridge/ebt_mark_t.h
include/linux/netfilter_ipv4.h
include/linux/nfsd/const.h
include/linux/nfsd/export.h
include/linux/nfsd/nfsd.h
include/linux/nfsd/nfsfh.h
include/linux/nfsd/stats.h
include/linux/nfsd/syscall.h
include/linux/nfsd/xdr.h
include/linux/nfsd/xdr3.h
include/linux/nfsd/xdr4.h
include/linux/nodemask.h
include/linux/notifier.h
include/linux/nsproxy.h [new file with mode: 0644]
include/linux/pci.h
include/linux/pci_ids.h
include/linux/pci_regs.h
include/linux/pid.h
include/linux/ppdev.h
include/linux/proc_fs.h
include/linux/pspace.h [new file with mode: 0644]
include/linux/raid/bitmap.h
include/linux/raid/md.h
include/linux/raid/md_k.h
include/linux/raid/md_u.h
include/linux/raid/raid1.h
include/linux/raid/raid10.h
include/linux/raid/raid5.h
include/linux/rcupdate.h
include/linux/sched.h
include/linux/scx200.h
include/linux/serial_core.h
include/linux/serio.h
include/linux/slab.h
include/linux/sound.h
include/linux/srcu.h [new file with mode: 0644]
include/linux/stat.h
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/syscalls.h
include/linux/tifm.h [new file with mode: 0644]
include/linux/topology.h
include/linux/tty_driver.h
include/linux/uinput.h
include/linux/unistd.h
include/linux/utsname.h
include/linux/videodev2.h
include/linux/vt_kern.h
include/linux/wavefront.h [deleted file]
include/linux/writeback.h
include/linux/xfrm.h
include/media/audiochip.h
include/mtd/Kbuild
include/mtd/mtd-abi.h
include/video/s1d13xxxfb.h
include/video/sstfb.h
init/Kconfig
init/do_mounts_initrd.c
init/do_mounts_md.c
init/main.c
init/version.c
ipc/mqueue.c
ipc/msg.c
ipc/msgutil.c
ipc/sem.c
ipc/shm.c
ipc/util.c
ipc/util.h
kernel/Makefile
kernel/auditfilter.c
kernel/auditsc.c
kernel/compat.c
kernel/dma.c
kernel/exit.c
kernel/fork.c
kernel/futex.c
kernel/irq/chip.c
kernel/irq/migration.c
kernel/kallsyms.c
kernel/kmod.c
kernel/kprobes.c
kernel/lockdep.c
kernel/module.c
kernel/nsproxy.c [new file with mode: 0644]
kernel/pid.c
kernel/posix-timers.c
kernel/power/snapshot.c
kernel/rcupdate.c
kernel/rcutorture.c
kernel/resource.c
kernel/sched.c
kernel/signal.c
kernel/srcu.c [new file with mode: 0644]
kernel/sys.c
kernel/sysctl.c
kernel/utsname.c [new file with mode: 0644]
kernel/workqueue.c
lib/Kconfig.debug
lib/Makefile
lib/cpumask.c
lib/errno.c [deleted file]
lib/genalloc.c
lib/reed_solomon/reed_solomon.c
lib/sort.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/bluetooth/rfcomm/tty.c
net/bridge/netfilter/ebt_mark.c
net/core/neighbour.c
net/core/skbuff.c
net/ipv4/Kconfig
net/ipv4/Makefile
net/ipv4/arp.c
net/ipv4/esp4.c
net/ipv4/ipcomp.c
net/ipv4/ipconfig.c
net/ipv4/ipvs/Kconfig
net/ipv4/ipvs/ip_vs_core.c
net/ipv4/netfilter.c
net/ipv4/netfilter/Kconfig
net/ipv4/netfilter/ip_nat_standalone.c
net/ipv4/netfilter/ipt_REJECT.c
net/ipv4/netfilter/iptable_mangle.c
net/ipv4/tcp_input.c
net/ipv4/tcp_probe.c
net/ipv4/udp.c
net/ipv4/xfrm4_mode_beet.c [new file with mode: 0644]
net/ipv6/Kconfig
net/ipv6/Makefile
net/ipv6/ipcomp6.c
net/ipv6/udp.c
net/ipv6/xfrm6_mode_beet.c [new file with mode: 0644]
net/irda/ircomm/ircomm_tty.c
net/netfilter/Kconfig
net/sched/estimator.c [deleted file]
net/sched/sch_htb.c
net/socket.c
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/auth_gss/svcauth_gss.c
net/sunrpc/clnt.c
net/sunrpc/sunrpc_syms.c
net/sunrpc/svc.c
net/sunrpc/svcauth_unix.c
net/sunrpc/svcsock.c
net/tipc/link.c
net/xfrm/xfrm_hash.h
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_state.c
net/xfrm/xfrm_user.c
scripts/.gitignore
scripts/Makefile.headersinst
scripts/Makefile.modpost
scripts/kconfig/Makefile
scripts/kconfig/confdata.c
scripts/kconfig/lxdialog/Makefile [deleted file]
scripts/kconfig/lxdialog/checklist.c
scripts/kconfig/lxdialog/colors.h [deleted file]
scripts/kconfig/lxdialog/dialog.h
scripts/kconfig/lxdialog/inputbox.c
scripts/kconfig/lxdialog/lxdialog.c [deleted file]
scripts/kconfig/lxdialog/menubox.c
scripts/kconfig/lxdialog/msgbox.c [deleted file]
scripts/kconfig/lxdialog/textbox.c
scripts/kconfig/lxdialog/util.c
scripts/kconfig/lxdialog/yesno.c
scripts/kconfig/mconf.c
scripts/kernel-doc
security/selinux/Kconfig
sound/core/info_oss.c
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/ite8172.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/trident.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 2aa8f6d41c2ff60abca66ef4e34af0407c7fe285..5329ead9c672f3f3f4a891c9d00929ca2af434f1 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
@@ -951,6 +955,12 @@ S: Brevia 1043
 S: S-114 79 Stockholm
 S: Sweden
 
+N: Pekka Enberg
+E: penberg@cs.helsinki.fi
+W: http://www.cs.helsinki.fi/u/penberg/
+D: Various kernel hacks, fixes, and cleanups.
+S: Finland
+
 N: David Engebretsen
 E: engebret@us.ibm.com
 D: Linux port to 64-bit PowerPC architecture
@@ -2003,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
@@ -2172,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
@@ -2228,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
@@ -2969,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.
@@ -3281,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/
@@ -3652,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 6d4b1ef5b6f11a24a1705e1c0e73b17220feb35c..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
@@ -325,8 +326,13 @@ X!Ekernel/module.c
 !Ekernel/irq/manage.c
      </sect1>
 
+     <sect1><title>DMA Channels</title>
+!Ekernel/dma.c
+     </sect1>
+
      <sect1><title>Resources Management</title>
 !Ikernel/resource.c
+!Ekernel/resource.c
      </sect1>
 
      <sect1><title>MTRR Handling</title>
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 7756e09ea7595a999c69311b5bb399054154826e..0e3924ecd76b4e9b197348d656712fee80a2691d 100644 (file)
@@ -364,6 +364,7 @@ You can change this at module load time (for a module) with:
        regspacings=<sp1>,<sp2>,... regsizes=<size1>,<size2>,...
        regshifts=<shift1>,<shift2>,...
        slave_addrs=<addr1>,<addr2>,...
+       force_kipmid=<enable1>,<enable2>,...
 
 Each of these except si_trydefaults is a list, the first item for the
 first interface, second item for the second interface, etc.
@@ -409,7 +410,13 @@ The slave_addrs specifies the IPMI address of the local BMC.  This is
 usually 0x20 and the driver defaults to that, but in case it's not, it
 can be specified when the driver starts up.
 
-When compiled into the kernel, the addresses can be specified on the
+The force_ipmid parameter forcefully enables (if set to 1) or disables
+(if set to 0) the kernel IPMI daemon.  Normally this is auto-detected
+by the driver, but systems with broken interrupts might need an enable,
+or users that don't want the daemon (don't need the performance, don't
+want the CPU hit) can disable it.
+
+When compiled into the kernel, the parameters can be specified on the
 kernel command line as:
 
   ipmi_si.type=<type1>,<type2>...
@@ -419,6 +426,7 @@ kernel command line as:
        ipmi_si.regsizes=<size1>,<size2>,...
        ipmi_si.regshifts=<shift1>,<shift2>,...
        ipmi_si.slave_addrs=<addr1>,<addr2>,...
+       ipmi_si.force_kipmid=<enable1>,<enable2>,...
 
 It works the same as the module parameters of the same names.
 
@@ -460,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 4f0d6bc789ef0fadf101eaa362fa3d829dc8a588..be3e7836abef235c5140cf7810eee84f27b8d835 100644 (file)
@@ -9,8 +9,9 @@ Intel 810/815 Framebuffer driver
 ================================================================
 
 A. Introduction
+
        This is a framebuffer driver for various Intel 810/815 compatible
-graphics devices.  These would include:
+       graphics devices.  These include:
 
        Intel 810
        Intel 810E
@@ -21,136 +22,136 @@ graphics devices.  These would include:
 
 B.  Features
 
-        - Choice of using Discrete Video Timings, VESA Generalized Timing
+       - Choice of using Discrete Video Timings, VESA Generalized Timing
          Formula, or a framebuffer specific database to set the video mode
 
-       - Supports a variable range of horizontal and vertical resolution, and
-         vertical refresh rates if the VESA Generalized Timing Formula is 
+       - Supports a variable range of horizontal and vertical resolution and
+         vertical refresh rates if the VESA Generalized Timing Formula is
          enabled.
 
-        - Supports color depths of 8, 16, 24 and 32 bits per pixel
+       - Supports color depths of 8, 16, 24 and 32 bits per pixel
 
        - Supports pseudocolor, directcolor, or truecolor visuals
 
-        - Full and optimized hardware acceleration at 8, 16 and 24 bpp
+       - Full and optimized hardware acceleration at 8, 16 and 24 bpp
 
        - Robust video state save and restore
 
-        - MTRR support 
+       - MTRR support
 
        - Utilizes user-entered monitor specifications to automatically
          calculate required video mode parameters.
 
-       - Can concurrently run with xfree86 running with native i810 drivers 
+       - Can concurrently run with xfree86 running with native i810 drivers
 
        - Hardware Cursor Support
  
        - Supports EDID probing either by DDC/I2C or through the BIOS
 
 C.  List of available options
-       
-   a. "video=i810fb"  
+
+   a. "video=i810fb"
        enables the i810 driver
 
        Recommendation: required
-   b. "xres:<value>"  
+
+   b. "xres:<value>"
        select horizontal resolution in pixels. (This parameter will be
        ignored if 'mode_option' is specified.  See 'o' below).
 
-       Recommendation: user preference 
+       Recommendation: user preference
        (default = 640)
 
    c. "yres:<value>"
        select vertical resolution in scanlines. If Discrete Video Timings
        is enabled, this will be ignored and computed as 3*xres/4.  (This
        parameter will be ignored if 'mode_option' is specified.  See 'o'
-       below)  
+       below)
 
        Recommendation: user preference
        (default = 480)
-               
-   d. "vyres:<value>" 
+
+   d. "vyres:<value>"
        select virtual vertical resolution in scanlines. If (0) or none
-       is specified, this will be computed against maximum available memory. 
+       is specified, this will be computed against maximum available memory.
 
        Recommendation: do not set
        (default = 480)
 
    e. "vram:<value>"
-       select amount of system RAM in MB to allocate for the video memory 
+       select amount of system RAM in MB to allocate for the video memory
 
        Recommendation: 1 - 4 MB.
        (default = 4)
 
-   f. "bpp:<value>"   
-       select desired pixel depth 
+   f. "bpp:<value>"
+       select desired pixel depth
 
        Recommendation: 8
        (default = 8)
 
-   g. "hsync1/hsync2:<value>" 
-       select the minimum and maximum Horizontal Sync Frequency of the 
-       monitor in KHz.  If a using a fixed frequency monitor, hsync1 must 
+   g. "hsync1/hsync2:<value>"
+       select the minimum and maximum Horizontal Sync Frequency of the
+       monitor in kHz.  If using a fixed frequency monitor, hsync1 must
        be equal to hsync2. If EDID probing is successful, these will be
        ignored and values will be taken from the EDID block.
 
        Recommendation: check monitor manual for correct values
-       default (29/30)
+       (default = 29/30)
 
-   h. "vsync1/vsync2:<value>" 
+   h. "vsync1/vsync2:<value>"
        select the minimum and maximum Vertical Sync Frequency of the monitor
-       in Hz. You can also use this option to lock your monitor's refresh 
+       in Hz. You can also use this option to lock your monitor's refresh
        rate. If EDID probing is successful, these will be ignored and values
        will be taken from the EDID block.
 
        Recommendation: check monitor manual for correct values
        (default = 60/60)
 
-       IMPORTANT:  If you need to clamp your timings, try to give some 
-       leeway for computational errors (over/underflows).  Example: if 
+       IMPORTANT:  If you need to clamp your timings, try to give some
+       leeway for computational errors (over/underflows).  Example: if
        using vsync1/vsync2 = 60/60, make sure hsync1/hsync2 has at least
        a 1 unit difference, and vice versa.
 
-   i. "voffset:<value>"        
-        select at what offset in MB of the logical memory to allocate the 
+   i. "voffset:<value>"
+       select at what offset in MB of the logical memory to allocate the
        framebuffer memory.  The intent is to avoid the memory blocks
        used by standard graphics applications (XFree86).  The default
-        offset (16 MB for a 64MB aperture, 8 MB for a 32MB aperture) will
-        avoid XFree86's usage and allows up to 7MB/15MB of framebuffer
-        memory.  Depending on your usage, adjust the value up or down, 
-       (0 for maximum usage, 31/63 MB for the least amount).  Note, an 
+       offset (16 MB for a 64 MB aperture, 8 MB for a 32 MB aperture) will
+       avoid XFree86's usage and allows up to 7 MB/15 MB of framebuffer
+       memory.  Depending on your usage, adjust the value up or down
+       (0 for maximum usage, 31/63 MB for the least amount).  Note, an
        arbitrary setting may conflict with XFree86.
 
        Recommendation: do not set
        (default = 8 or 16 MB)
-      
-   j. "accel" 
-       enable text acceleration.  This can be enabled/reenabled anytime 
-       by using 'fbset -accel true/false'. 
+
+   j. "accel"
+       enable text acceleration.  This can be enabled/reenabled anytime
+       by using 'fbset -accel true/false'.
 
        Recommendation: enable
-       (default = not set) 
+       (default = not set)
 
-   k. "mtrr" 
+   k. "mtrr"
        enable MTRR.  This allows data transfers to the framebuffer memory
        to occur in bursts which can significantly increase performance.
-       Not very helpful with the i810/i815 because of 'shared memory'. 
+       Not very helpful with the i810/i815 because of 'shared memory'.
 
        Recommendation: do not set
-       (default = not set) 
+       (default = not set)
 
    l. "extvga"
        if specified, secondary/external VGA output will always be enabled.
        Useful if the BIOS turns off the VGA port when no monitor is attached.
-       The external VGA monitor can then be attached without rebooting. 
+       The external VGA monitor can then be attached without rebooting.
 
        Recommendation: do not set
        (default = not set)
-       
-   m. "sync" 
+
+   m. "sync"
        Forces the hardware engine to do a "sync" or wait for the hardware
-       to finish before starting another instruction. This will produce a 
+       to finish before starting another instruction. This will produce a
        more stable setup, but will be slower.
 
        Recommendation: do not set
@@ -162,6 +163,7 @@ C.  List of available options
 
        Recommendation: do not set
        (default = not set)
+
    o. <xres>x<yres>[-<bpp>][@<refresh>]
        The driver will now accept specification of boot mode option.  If this
        is specified, the options 'xres' and 'yres' will be ignored. See
@@ -183,8 +185,8 @@ append="video=i810fb:vram:2,xres:1024,yres:768,bpp:8,hsync1:30,hsync2:55, \
         vsync1:50,vsync2:85,accel,mtrr"
 
 This will initialize the framebuffer to 1024x768 at 8bpp.  The framebuffer
-will use 2 MB of System RAM. MTRR support will be enabled. The refresh rate 
-will be computed based on the hsync1/hsync2 and vsync1/vsync2 values.  
+will use 2 MB of System RAM. MTRR support will be enabled. The refresh rate
+will be computed based on the hsync1/hsync2 and vsync1/vsync2 values.
 
 IMPORTANT:
 You must include hsync1, hsync2, vsync1 and vsync2 to enable video modes
@@ -194,10 +196,10 @@ vsync1 and vsync2 parameters.  These parameters will be taken from the EDID
 block.
 
 E.  Module options
-       
-       The module parameters are essentially similar to the kernel 
-parameters. The main difference is that you need to include a Boolean value 
-(1 for TRUE, and 0 for FALSE) for those options which don't need a value. 
+
+The module parameters are essentially similar to the kernel
+parameters. The main difference is that you need to include a Boolean value
+(1 for TRUE, and 0 for FALSE) for those options which don't need a value.
 
 Example, to enable MTRR, include "mtrr=1".
 
@@ -214,62 +216,62 @@ Or just add the following to /etc/modprobe.conf
        options i810fb vram=2 xres=1024 bpp=16 hsync1=30 hsync2=55 vsync1=50 \
        vsync2=85 accel=1 mtrr=1
 
-and just do a 
+and just do a
 
        modprobe i810fb
 
 
 F.  Setup
 
-       a. Do your usual method of configuring the kernel. 
-       
+       a. Do your usual method of configuring the kernel.
+
        make menuconfig/xconfig/config
 
-       b. Under "Code Maturity Options", enable "Prompt for experimental/
-          incomplete code/drivers".
+       b. Under "Code maturity level options" enable "Prompt for development
+          and/or incomplete code/drivers".
 
        c. Enable agpgart support for the Intel 810/815 on-board graphics.
-          This is required.  The option is under "Character Devices"
+          This is required.  The option is under "Character Devices".
 
        d. Under "Graphics Support", select "Intel 810/815" either statically
           or as a module.  Choose "use VESA Generalized Timing Formula" if
-          you need to maximize the capability of your display.  To be on the 
-          safe side, you can leave this unselected.  
-  
+          you need to maximize the capability of your display.  To be on the
+          safe side, you can leave this unselected.
+
        e. If you want support for DDC/I2C probing (Plug and Play Displays),
           set 'Enable DDC Support' to 'y'. To make this option appear, set
           'use VESA Generalized Timing Formula' to 'y'.
 
-        f. If you want a framebuffer console, enable it under "Console 
-          Drivers"
+        f. If you want a framebuffer console, enable it under "Console
+          Drivers".
+
+       g. Compile your kernel.
+
+       h. Load the driver as described in sections D and E.
 
-       g. Compile your kernel. 
-               
-       h. Load the driver as described in section D and E.
-       
        i.  Try the DirectFB (http://www.directfb.org) + the i810 gfxdriver
            patch to see the chipset in action (or inaction :-).
 
 G.  Acknowledgment:
-       
+
        1.  Geert Uytterhoeven - his excellent howto and the virtual
-                                 framebuffer driver code made this possible.
+           framebuffer driver code made this possible.
 
-       2.  Jeff Hartmann for his agpgart code.  
+       2.  Jeff Hartmann for his agpgart code.
 
        3.  The X developers.  Insights were provided just by reading the
            XFree86 source code.
 
        4.  Intel(c).  For this value-oriented chipset driver and for
-            providing documentation.
+           providing documentation.
 
        5. Matt Sottek.  His inputs and ideas  helped in making some
-       optimizations possible.
+          optimizations possible.
 
 H.  Home Page:
 
        A more complete, and probably updated information is provided at
-http://i810fb.sourceforge.net.
+       http://i810fb.sourceforge.net.
 
 ###########################
 Tony
index aa0d322db171d1175bee86f2e85448a94ceff8d7..da5ee74219e8c55016dda1f8d1a6fb4820e5e717 100644 (file)
@@ -88,12 +88,20 @@ Sample Usage
 
 In /etc/lilo.conf, add the line:
 
-append="video=intelfb:800x600-32@75,accel,hwcursor,vram=8"
+append="video=intelfb:mode=800x600-32@75,accel,hwcursor,vram=8"
 
 This will initialize the framebuffer to 800x600 at 32bpp and 75Hz. The
 framebuffer will use 8 MB of System RAM. hw acceleration of text and cursor
 will be enabled.
 
+Remarks
+-------
+
+If setting this parameter doesn't work (you stay in a 80x25 text-mode),
+you might need to set the "vga=<mode>" parameter too - see vesafb.txt
+in this directory.
+
+
 D.  Module options
 
        The module parameters are essentially similar to the kernel
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 9364f47c711690e4a262ed0c93c1072ff1be181e..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
@@ -122,15 +114,6 @@ Who:    Arjan van de Ven
 
 ---------------------------
 
-What:  START_ARRAY ioctl for md
-When:  July 2006
-Files: drivers/md/md.c
-Why:   Not reliable by design - can fail when most needed.
-       Alternatives exist
-Who:   NeilBrown <neilb@suse.de>
-
----------------------------
-
 What:   eepro100 network driver
 When:   January 2007
 Why:    replaced by the e100 driver
@@ -193,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
@@ -220,42 +203,6 @@ Who:       Nick Piggin <npiggin@suse.de>
 
 ---------------------------
 
-What:  Support for the Momentum / PMC-Sierra Jaguar ATX evaluation board
-When:  September 2006
-Why:   Does no longer build since quite some time, and was never popular,
-       due to the platform being replaced by successor models.  Apparently
-       no user base left.  It also is one of the last users of
-       WANT_PAGE_VIRTUAL.
-Who:   Ralf Baechle <ralf@linux-mips.org>
-
----------------------------
-
-What:  Support for the Momentum Ocelot, Ocelot 3, Ocelot C and Ocelot G
-When:  September 2006
-Why:   Some do no longer build and apparently there is no user base left
-       for these platforms.
-Who:   Ralf Baechle <ralf@linux-mips.org>
-
----------------------------
-
-What:  Support for MIPS Technologies' Altas and SEAD evaluation board
-When:  September 2006
-Why:   Some do no longer build and apparently there is no user base left
-       for these platforms.  Hardware out of production since several years.
-Who:   Ralf Baechle <ralf@linux-mips.org>
-
----------------------------
-
-What:  Support for the IT8172-based platforms, ITE 8172G and Globespan IVR
-When:  September 2006
-Why:   Code does no longer build since at least 2.6.0,  apparently there is
-       no user base left for these platforms.  Hardware out of production
-       since several years and hardly a trace of the manufacturer left on
-       the net.
-Who:   Ralf Baechle <ralf@linux-mips.org>
-
----------------------------
-
 What:  Interrupt only SA_* flags
 When:  Januar 2007
 Why:   The interrupt related SA_* flags are replaced by IRQF_* to move them
@@ -325,3 +272,11 @@ Why:       i2c-isa is a non-sense and doesn't fit in the device driver
 Who:   Jean Delvare <khali@linux-fr.org>
 
 ---------------------------
+
+What:  ftape
+When:  2.6.20
+Why:   Orphaned for ages.  SMP bugs long unfixed.  Few users left
+       in the world.
+Who:   Jeff Garzik <jeff@garzik.org>
+
+---------------------------
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 f51eb4bc2ff1e1635c0ca1b14c9db9e90de2fb56..040b9773209fe173e61f4c79d23db74ecf6c0118 100644 (file)
@@ -124,6 +124,13 @@ TROUBLESHOOTING SERIAL CONSOLE PROBLEMS
 
        - Add entry to /etc/securetty for console tty.
 
+    No ACPI serial devices found in 2.6.17 or later:
+
+       - Turn on CONFIG_PNP and CONFIG_PNPACPI.  Prior to 2.6.17, ACPI
+         serial devices were discovered by 8250_acpi.  In 2.6.17,
+         8250_acpi was replaced by the combination of 8250_pnp and
+         CONFIG_PNPACPI.
+
 
 
 [1] http://www.dig64.org/specifications/DIG64_PCDPv20.pdf
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 c7e10eaff203c595e3ba99bd77540e7b86889723..085eb15b45b7c5655d0c8363e19bdde2cf4e4699 100644 (file)
@@ -1,78 +1,48 @@
 Force feedback for Linux.
 By Johann Deneux <deneux@ifrance.com> on 2001/04/22.
+Updated by Anssi Hannula <anssi.hannula@gmail.com> on 2006/04/09.
 You may redistribute this file. Please remember to include shape.fig and
 interactive.fig as well.
 ----------------------------------------------------------------------------
 
-0. Introduction
+1. Introduction
 ~~~~~~~~~~~~~~~
 This document describes how to use force feedback devices under Linux. The
 goal is not to support these devices as if they were simple input-only devices
 (as it is already the case), but to really enable the rendering of force
 effects.
-At the moment, only I-Force devices are supported, and not officially. That
-means I had to find out how the protocol works on my own. Of course, the
-information I managed to grasp is far from being complete, and I can not
-guarranty that this driver will work for you.
-This document only describes the force feedback part of the driver for I-Force
-devices. Please read joystick.txt before reading further this document.
+This document only describes the force feedback part of the Linux input
+interface. Please read joystick.txt and input.txt before reading further this
+document.
 
 2. Instructions to the user
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Here are instructions on how to compile and use the driver. In fact, this
-driver is the normal iforce, input and evdev drivers written by Vojtech
-Pavlik, plus additions to support force feedback.
+To enable force feedback, you have to:
+
+1. have your kernel configured with evdev and a driver that supports your
+   device.
+2. make sure evdev module is loaded and /dev/input/event* device files are
+   created.
 
 Before you start, let me WARN you that some devices shake violently during the
 initialisation phase. This happens for example with my "AVB Top Shot Pegasus".
 To stop this annoying behaviour, move you joystick to its limits. Anyway, you
-should keep a hand on your device, in order to avoid it to brake down if
+should keep a hand on your device, in order to avoid it to break down if
 something goes wrong.
 
-At the kernel's compilation:
-       - Enable IForce/Serial
-       - Enable Event interface
-
-Compile the modules, install them.
-
-You also need inputattach.
-
-You then need to insert the modules into the following order:
-% modprobe joydev
-% modprobe serport             # Only for serial
-% modprobe iforce
-% modprobe evdev
-% ./inputattach -ifor $2 &     # Only for serial
-If you are using USB, you don't need the inputattach step.
-
-Please check that you have all the /dev/input entries needed:
-cd /dev
-rm js*
-mkdir input
-mknod input/js0 c 13 0
-mknod input/js1 c 13 1
-mknod input/js2 c 13 2
-mknod input/js3 c 13 3
-ln -s input/js0 js0
-ln -s input/js1 js1
-ln -s input/js2 js2
-ln -s input/js3 js3
-
-mknod input/event0 c 13 64
-mknod input/event1 c 13 65
-mknod input/event2 c 13 66
-mknod input/event3 c 13 67
+If you have a serial iforce device, you need to start inputattach. See
+joystick.txt for details.
 
 2.1 Does it work ?
 ~~~~~~~~~~~~~~~~~~
 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()
+All interactions are done using the event API. That is, you can use ioctl()
 and write() on /dev/input/eventXX.
-  This information is subject to change.
+This information is subject to change.
 
 3.1 Querying device capabilities
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -86,18 +56,29 @@ int ioctl(int file_descriptor, int request, unsigned long *features);
 
 Returns the features supported by the device. features is a bitfield with the
 following bits:
-- FF_X         has an X axis (usually joysticks)
-- FF_Y         has an Y axis (usually joysticks)
-- FF_WHEEL     has a wheel (usually sterring wheels)
 - FF_CONSTANT  can render constant force effects
-- FF_PERIODIC  can render periodic effects (sine, triangle, square...)
+- FF_PERIODIC  can render periodic effects with the following waveforms:
+  - FF_SQUARE    square waveform
+  - FF_TRIANGLE          triangle waveform
+  - FF_SINE      sine waveform
+  - FF_SAW_UP    sawtooth up waveform
+  - FF_SAW_DOWN          sawtooth down waveform
+  - FF_CUSTOM    custom waveform
 - FF_RAMP       can render ramp effects
 - FF_SPRING    can simulate the presence of a spring
-- FF_FRICTION  can simulate friction 
+- FF_FRICTION  can simulate friction
 - FF_DAMPER    can simulate damper effects
-- FF_RUMBLE    rumble effects (normally the only effect supported by rumble
-               pads)
+- FF_RUMBLE    rumble effects
 - FF_INERTIA    can simulate inertia
+- FF_GAIN      gain is adjustable
+- FF_AUTOCENTER        autocenter is adjustable
+
+Note: In most cases you should use FF_PERIODIC instead of FF_RUMBLE. All
+      devices that support FF_RUMBLE support FF_PERIODIC (square, triangle,
+      sine) and the other way around.
+
+Note: The exact syntax FF_CUSTOM is undefined for the time being as no driver
+      supports it yet.
 
 
 int ioctl(int fd, EVIOCGEFFECTS, int *n);
@@ -108,7 +89,7 @@ Returns the number of effects the device can keep in its memory.
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 #include <linux/input.h>
 #include <sys/ioctl.h>
+
 int ioctl(int file_descriptor, int request, struct ff_effect *effect);
 
 "request" must be EVIOCSFF.
@@ -120,6 +101,9 @@ to the unique id assigned by the driver. This data is required for performing
 some operations (removing an effect, controlling the playback).
 This if field must be set to -1 by the user in order to tell the driver to
 allocate a new effect.
+
+Effects are file descriptor specific.
+
 See <linux/input.h> for a description of the ff_effect struct. You should also
 find help in a few sketches, contained in files shape.fig and interactive.fig.
 You need xfig to visualize these files.
@@ -128,8 +112,8 @@ You need xfig to visualize these files.
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 int ioctl(int fd, EVIOCRMFF, effect.id);
 
-This makes room for new effects in the device's memory. Please note this won't
-stop the effect if it was playing.
+This makes room for new effects in the device's memory. Note that this also
+stops the effect if it was playing.
 
 3.4 Controlling the playback of effects
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -149,22 +133,21 @@ Control of playing is done with write(). Below is an example:
        play.type = EV_FF;
        play.code = effect.id;
        play.value = 3;
-       
+
        write(fd, (const void*) &play, sizeof(play));
 ...
        /* Stop an effect */
        stop.type = EV_FF;
        stop.code = effect.id;
        stop.value = 0;
-       
+
        write(fd, (const void*) &play, sizeof(stop));
 
 3.5 Setting the gain
 ~~~~~~~~~~~~~~~~~~~~
 Not all devices have the same strength. Therefore, users should set a gain
 factor depending on how strong they want effects to be. This setting is
-persistent across access to the driver, so you should not care about it if
-you are writing games, as another utility probably already set this for you.
+persistent across access to the driver.
 
 /* Set the gain of the device
 int gain;              /* between 0 and 100 */
@@ -204,11 +187,14 @@ type of device, not all parameters can be dynamically updated. For example,
 the direction of an effect cannot be updated with iforce devices. In this
 case, the driver stops the effect, up-load it, and restart it.
 
+Therefore it is recommended to dynamically change direction while the effect
+is playing only when it is ok to restart the effect with a replay count of 1.
 
 3.8 Information about the status of effects
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Every time the status of an effect is changed, an event is sent. The values
 and meanings of the fields of the event are as follows:
+
 struct input_event {
 /* When the status of the effect changed */
        struct timeval time;
@@ -225,3 +211,9 @@ struct input_event {
 
 FF_STATUS_STOPPED      The effect stopped playing
 FF_STATUS_PLAYING      The effect started to play
+
+NOTE: Status feedback is only supported by iforce driver. If you have
+      a really good reason to use this, please contact
+      linux-joystick@atrey.karlin.mff.cuni.cz or anssi.hannula@gmail.com
+      so that support for it can be added to the rest of the drivers.
+
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 2e7702e94a786c0942c91134da25fef40ecc07b4..769ee05ee4d1f6da279386c2325ff5f80e322570 100644 (file)
@@ -43,7 +43,7 @@ are not planned to be included in the kernel tree.
 What is covered within this file is mainly information to authors
 of modules. The author of an external module should supply
 a makefile that hides most of the complexity, so one only has to type
-'make' to build the module. A complete example will be present in
+'make' to build the module. A complete example will be presented in
 chapter 4, "Creating a kbuild file for an external module".
 
 
@@ -61,6 +61,7 @@ when building an external module.
                make -C <path-to-kernel> M=`pwd`
 
        For the running kernel use:
+
                make -C /lib/modules/`uname -r`/build M=`pwd`
 
        For the above command to succeed, the kernel must have been
@@ -130,10 +131,10 @@ when building an external module.
 
        To make sure the kernel contains the information required to
        build external modules the target 'modules_prepare' must be used.
-       'module_prepare' exists solely as a simple way to prepare
+       'modules_prepare' exists solely as a simple way to prepare
        a kernel source tree for building external modules.
        Note: modules_prepare will not build Module.symvers even if
-       CONFIG_MODULEVERSIONING is set. Therefore a full kernel build
+       CONFIG_MODVERSIONS is set. Therefore a full kernel build
        needs to be executed to make module versioning work.
 
 --- 2.5 Building separate files for a module
@@ -450,7 +451,7 @@ kernel refuses to load the module.
 
 Module.symvers contains a list of all exported symbols from a kernel build.
 
---- 7.1 Symbols fron the kernel (vmlinux + modules)
+--- 7.1 Symbols from the kernel (vmlinux + modules)
 
        During a kernel build, a file named Module.symvers will be generated.
        Module.symvers contains all exported symbols from the kernel and
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 2c3b1eae42801ae38fe9fe4eb2174f15b44c89f3..ba26201d50234ba3c78e2c0c9084b1d6d25d7110 100644 (file)
@@ -151,9 +151,9 @@ So that you can load and unload Kprobes-based instrumentation modules,
 make sure "Loadable module support" (CONFIG_MODULES) and "Module
 unloading" (CONFIG_MODULE_UNLOAD) are set to "y".
 
-You may also want to ensure that CONFIG_KALLSYMS and perhaps even
-CONFIG_KALLSYMS_ALL are set to "y", since kallsyms_lookup_name()
-is a handy, version-independent way to find a function's address.
+Also make sure that CONFIG_KALLSYMS and perhaps even CONFIG_KALLSYMS_ALL
+are set to "y", since kallsyms_lookup_name() is used by the in-kernel
+kprobe address resolution code.
 
 If you need to insert a probe in the middle of a function, you may find
 it useful to "Compile the kernel with debug info" (CONFIG_DEBUG_INFO),
@@ -179,6 +179,27 @@ occurs during execution of kp->pre_handler or kp->post_handler,
 or during single-stepping of the probed instruction, Kprobes calls
 kp->fault_handler.  Any or all handlers can be NULL.
 
+NOTE:
+1. With the introduction of the "symbol_name" field to struct kprobe,
+the probepoint address resolution will now be taken care of by the kernel.
+The following will now work:
+
+       kp.symbol_name = "symbol_name";
+
+(64-bit powerpc intricacies such as function descriptors are handled
+transparently)
+
+2. Use the "offset" field of struct kprobe if the offset into the symbol
+to install a probepoint is known. This field is used to calculate the
+probepoint.
+
+3. Specify either the kprobe "symbol_name" OR the "addr". If both are
+specified, kprobe registration will fail with -EINVAL.
+
+4. With CISC architectures (such as i386 and x86_64), the kprobes code
+does not validate if the kprobe.addr is at an instruction boundary.
+Use "offset" with caution.
+
 register_kprobe() returns 0 on success, or a negative errno otherwise.
 
 User's pre-handler (kp->pre_handler):
@@ -225,6 +246,12 @@ control to Kprobes.)  If the probed function is declared asmlinkage,
 fastcall, or anything else that affects how args are passed, the
 handler's declaration must match.
 
+NOTE: A macro JPROBE_ENTRY is provided to handle architecture-specific
+aliasing of jp->entry. In the interest of portability, it is advised
+to use:
+
+       jp->entry = JPROBE_ENTRY(handler);
+
 register_jprobe() returns 0 on success, or a negative errno otherwise.
 
 4.3 register_kretprobe
@@ -251,6 +278,11 @@ of interest:
 - ret_addr: the return address
 - rp: points to the corresponding kretprobe object
 - task: points to the corresponding task struct
+
+The regs_return_value(regs) macro provides a simple abstraction to
+extract the return value from the appropriate register as defined by
+the architecture's ABI.
+
 The handler's return value is currently ignored.
 
 4.4 unregister_*probe
@@ -369,7 +401,6 @@ stack trace and selected i386 registers when do_fork() is called.
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/kprobes.h>
-#include <linux/kallsyms.h>
 #include <linux/sched.h>
 
 /*For each probe you need to allocate a kprobe structure*/
@@ -403,18 +434,14 @@ int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr)
        return 0;
 }
 
-int init_module(void)
+static int __init kprobe_init(void)
 {
        int ret;
        kp.pre_handler = handler_pre;
        kp.post_handler = handler_post;
        kp.fault_handler = handler_fault;
-       kp.addr = (kprobe_opcode_t*) kallsyms_lookup_name("do_fork");
-       /* register the kprobe now */
-       if (!kp.addr) {
-               printk("Couldn't find %s to plant kprobe\n", "do_fork");
-               return -1;
-       }
+       kp.symbol_name = "do_fork";
+
        if ((ret = register_kprobe(&kp) < 0)) {
                printk("register_kprobe failed, returned %d\n", ret);
                return -1;
@@ -423,12 +450,14 @@ int init_module(void)
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit kprobe_exit(void)
 {
        unregister_kprobe(&kp);
        printk("kprobe unregistered\n");
 }
 
+module_init(kprobe_init)
+module_exit(kprobe_exit)
 MODULE_LICENSE("GPL");
 ----- cut here -----
 
@@ -463,7 +492,6 @@ the arguments of do_fork().
 #include <linux/fs.h>
 #include <linux/uio.h>
 #include <linux/kprobes.h>
-#include <linux/kallsyms.h>
 
 /*
  * Jumper probe for do_fork.
@@ -485,17 +513,13 @@ long jdo_fork(unsigned long clone_flags, unsigned long stack_start,
 }
 
 static struct jprobe my_jprobe = {
-       .entry = (kprobe_opcode_t *) jdo_fork
+       .entry = JPROBE_ENTRY(jdo_fork)
 };
 
-int init_module(void)
+static int __init jprobe_init(void)
 {
        int ret;
-       my_jprobe.kp.addr = (kprobe_opcode_t *) kallsyms_lookup_name("do_fork");
-       if (!my_jprobe.kp.addr) {
-               printk("Couldn't find %s to plant jprobe\n", "do_fork");
-               return -1;
-       }
+       my_jprobe.kp.symbol_name = "do_fork";
 
        if ((ret = register_jprobe(&my_jprobe)) <0) {
                printk("register_jprobe failed, returned %d\n", ret);
@@ -506,12 +530,14 @@ int init_module(void)
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit jprobe_exit(void)
 {
        unregister_jprobe(&my_jprobe);
        printk("jprobe unregistered\n");
 }
 
+module_init(jprobe_init)
+module_exit(jprobe_exit)
 MODULE_LICENSE("GPL");
 ----- cut here -----
 
@@ -530,16 +556,13 @@ report failed calls to sys_open().
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/kprobes.h>
-#include <linux/kallsyms.h>
 
 static const char *probed_func = "sys_open";
 
 /* Return-probe handler: If the probed function fails, log the return value. */
 static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
 {
-       // Substitute the appropriate register name for your architecture --
-       // e.g., regs->rax for x86_64, regs->gpr[3] for ppc64.
-       int retval = (int) regs->eax;
+       int retval = regs_return_value(regs);
        if (retval < 0) {
                printk("%s returns %d\n", probed_func, retval);
        }
@@ -552,15 +575,11 @@ static struct kretprobe my_kretprobe = {
        .maxactive = 20
 };
 
-int init_module(void)
+static int __init kretprobe_init(void)
 {
        int ret;
-       my_kretprobe.kp.addr =
-               (kprobe_opcode_t *) kallsyms_lookup_name(probed_func);
-       if (!my_kretprobe.kp.addr) {
-               printk("Couldn't find %s to plant return probe\n", probed_func);
-               return -1;
-       }
+       my_kretprobe.kp.symbol_name = (char *)probed_func;
+
        if ((ret = register_kretprobe(&my_kretprobe)) < 0) {
                printk("register_kretprobe failed, returned %d\n", ret);
                return -1;
@@ -569,7 +588,7 @@ int init_module(void)
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit kretprobe_exit(void)
 {
        unregister_kretprobe(&my_kretprobe);
        printk("kretprobe unregistered\n");
@@ -578,6 +597,8 @@ void cleanup_module(void)
                my_kretprobe.nmissed, probed_func);
 }
 
+module_init(kretprobe_init)
+module_exit(kretprobe_exit)
 MODULE_LICENSE("GPL");
 ----- cut here -----
 
@@ -590,3 +611,5 @@ messages.)
 For additional information on Kprobes, refer to the following URLs:
 http://www-106.ibm.com/developerworks/library/l-kprobes.html?ca=dgr-lnxw42Kprobe
 http://www.redhat.com/magazine/005mar05/features/kprobes/
+http://www-users.cs.umn.edu/~boutcher/kprobes/
+http://www.linuxsymposium.org/2006/linuxsymposium_procv2.pdf (pages 101-115)
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 0668f9dc9d29635393e5876b15b1a3bce9abaa13..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
@@ -154,11 +154,12 @@ contains further md-specific information about the device.
 
 All md devices contain:
   level
-     a text file indicating the 'raid level'.  This may be a standard
-     numerical level prefixed by "RAID-" - e.g. "RAID-5", or some
-     other name such as "linear" or "multipath".
+     a text file indicating the 'raid level'. e.g. raid0, raid1,
+     raid5, linear, multipath, faulty.
      If no raid level has been set yet (array is still being
-     assembled), this file will be empty.
+     assembled), the value will reflect whatever has been written
+     to it, which may be a name like the above, or may be a number
+     such as '0', '5', etc.
 
   raid_disks
      a text file with a simple number indicating the number of devices
@@ -174,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
@@ -192,14 +193,6 @@ All md devices contain:
      1.2 (newer format in varying locations) or "none" indicating that
      the kernel isn't managing metadata at all.
 
-  level
-     The raid 'level' for this array.  The name will often (but not
-     always) be the same as the name of the module that implements the
-     level.  To be auto-loaded the module must have an alias
-        md-$LEVEL  e.g. md-raid5
-     This can be written only while the array is being assembled, not
-     after it is started.
-
   layout
      The "layout" for the array for the particular level.  This is
      simply a number that is interpretted differently by different
@@ -221,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.
@@ -314,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.
@@ -337,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.
 
@@ -360,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,
@@ -410,6 +403,15 @@ also have
       than sectors, this my be larger than the number of actual errors
       by a factor of the number of sectors in a page.
 
+   bitmap_set_bits
+      If the array has a write-intent bitmap, then writing to this
+      attribute can set bits in the bitmap, indicating that a resync
+      would need to check the corresponding blocks. Either individual
+      numbers or start-end pairs can be written.  Multiple numbers
+      can be separated by a space.
+      Note that the numbers are 'bit' numbers, not 'block' numbers.
+      They should be scaled by the bitmap_chunksize.
+
 Each active md device may also have attributes specific to the
 personality module that manages it.
 These are specific to the implementation of the module and could
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 5c0ba235f5a5de9416244b8ef6417ed159987857..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.
 
 
@@ -1441,6 +1440,258 @@ platforms are moved over to use the flattened-device-tree model.
                descriptor-types-mask = <012b0ebf>;
        };
 
+   h) Board Control and Status (BCSR)
+
+   Required properties:
+
+    - device_type : Should be "board-control"
+    - reg : Offset and length of the register set for the device
+
+    Example:
+
+       bcsr@f8000000 {
+               device_type = "board-control";
+               reg = <f8000000 8000>;
+       };
+
+   i) Freescale QUICC Engine module (QE)
+   This represents qe module that is installed on PowerQUICC II Pro.
+   Hopefully it will merge backward compatibility with CPM/CPM2.
+   Basically, it is a bus of devices, that could act more or less
+   as a complete entity (UCC, USB etc ). All of them should be siblings on
+   the "root" qe node, using the common properties from there.
+   The description below applies to the the qe of MPC8360 and
+   more nodes and properties would be extended in the future.
+
+   i) Root QE device
+
+   Required properties:
+   - device_type : should be "qe";
+   - model : precise model of the QE, Can be "QE", "CPM", or "CPM2"
+   - reg : offset and length of the device registers.
+   - bus-frequency : the clock frequency for QUICC Engine.
+
+   Recommended properties
+   - brg-frequency : the internal clock source frequency for baud-rate
+     generators in Hz.
+
+   Example:
+       qe@e0100000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               #interrupt-cells = <2>;
+               device_type = "qe";
+               model = "QE";
+               ranges = <0 e0100000 00100000>;
+               reg = <e0100000 480>;
+               brg-frequency = <0>;
+               bus-frequency = <179A7B00>;
+       }
+
+
+   ii) SPI (Serial Peripheral Interface)
+
+   Required properties:
+   - device_type : should be "spi".
+   - compatible : should be "fsl_spi".
+   - mode : the spi operation mode, it can be "cpu" or "qe".
+   - reg : Offset and length of the register set for the device
+   - interrupts : <a b> where a is the interrupt number and b is a
+     field that represents an encoding of the sense and level
+     information for the interrupt.  This should be encoded based on
+     the information in section 2) depending on the type of interrupt
+     controller you have.
+   - interrupt-parent : the phandle for the interrupt controller that
+     services interrupts for this device.
+
+   Example:
+       spi@4c0 {
+               device_type = "spi";
+               compatible = "fsl_spi";
+               reg = <4c0 40>;
+               interrupts = <82 0>;
+               interrupt-parent = <700>;
+               mode = "cpu";
+       };
+
+
+   iii) USB (Universal Serial Bus Controller)
+
+   Required properties:
+   - device_type : should be "usb".
+   - compatible : could be "qe_udc" or "fhci-hcd".
+   - mode : the could be "host" or "slave".
+   - reg : Offset and length of the register set for the device
+   - interrupts : <a b> where a is the interrupt number and b is a
+     field that represents an encoding of the sense and level
+     information for the interrupt.  This should be encoded based on
+     the information in section 2) depending on the type of interrupt
+     controller you have.
+   - interrupt-parent : the phandle for the interrupt controller that
+     services interrupts for this device.
+
+   Example(slave):
+       usb@6c0 {
+               device_type = "usb";
+               compatible = "qe_udc";
+               reg = <6c0 40>;
+               interrupts = <8b 0>;
+               interrupt-parent = <700>;
+               mode = "slave";
+       };
+
+
+   iv) UCC (Unified Communications Controllers)
+
+   Required properties:
+   - device_type : should be "network", "hldc", "uart", "transparent"
+    "bisync" or "atm".
+   - compatible : could be "ucc_geth" or "fsl_atm" and so on.
+   - model : should be "UCC".
+   - device-id : the ucc number(1-8), corresponding to UCCx in UM.
+   - reg : Offset and length of the register set for the device
+   - interrupts : <a b> where a is the interrupt number and b is a
+     field that represents an encoding of the sense and level
+     information for the interrupt.  This should be encoded based on
+     the information in section 2) depending on the type of interrupt
+     controller you have.
+   - interrupt-parent : the phandle for the interrupt controller that
+     services interrupts for this device.
+   - pio-handle : The phandle for the Parallel I/O port configuration.
+   - rx-clock : represents the UCC receive clock source.
+     0x00 : clock source is disabled;
+     0x1~0x10 : clock source is BRG1~BRG16 respectively;
+     0x11~0x28: clock source is QE_CLK1~QE_CLK24 respectively.
+   - tx-clock: represents the UCC transmit clock source;
+     0x00 : clock source is disabled;
+     0x1~0x10 : clock source is BRG1~BRG16 respectively;
+     0x11~0x28: clock source is QE_CLK1~QE_CLK24 respectively.
+
+   Required properties for network device_type:
+   - mac-address : list of bytes representing the ethernet address.
+   - phy-handle : The phandle for the PHY connected to this controller.
+
+   Example:
+       ucc@2000 {
+               device_type = "network";
+               compatible = "ucc_geth";
+               model = "UCC";
+               device-id = <1>;
+               reg = <2000 200>;
+               interrupts = <a0 0>;
+               interrupt-parent = <700>;
+               mac-address = [ 00 04 9f 00 23 23 ];
+               rx-clock = "none";
+               tx-clock = "clk9";
+               phy-handle = <212000>;
+               pio-handle = <140001>;
+       };
+
+
+   v) Parallel I/O Ports
+
+   This node configures Parallel I/O ports for CPUs with QE support.
+   The node should reside in the "soc" node of the tree.  For each
+   device that using parallel I/O ports, a child node should be created.
+   See the definition of the Pin configuration nodes below for more
+   information.
+
+   Required properties:
+   - device_type : should be "par_io".
+   - reg : offset to the register set and its length.
+   - num-ports : number of Parallel I/O ports
+
+   Example:
+       par_io@1400 {
+               reg = <1400 100>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               device_type = "par_io";
+               num-ports = <7>;
+               ucc_pin@01 {
+                       ......
+               };
+
+
+   vi) Pin configuration nodes
+
+   Required properties:
+   - linux,phandle : phandle of this node; likely referenced by a QE
+     device.
+   - pio-map : array of pin configurations.  Each pin is defined by 6
+     integers.  The six numbers are respectively: port, pin, dir,
+     open_drain, assignment, has_irq.
+     - port : port number of the pin; 0-6 represent port A-G in UM.
+     - pin : pin number in the port.
+     - dir : direction of the pin, should encode as follows:
+
+       0 = The pin is disabled
+       1 = The pin is an output
+       2 = The pin is an input
+       3 = The pin is I/O
+
+     - open_drain : indicates the pin is normal or wired-OR:
+
+       0 = The pin is actively driven as an output
+       1 = The pin is an open-drain driver. As an output, the pin is
+           driven active-low, otherwise it is three-stated.
+
+     - assignment : function number of the pin according to the Pin Assignment
+       tables in User Manual.  Each pin can have up to 4 possible functions in
+       QE and two options for CPM.
+     - has_irq : indicates if the pin is used as source of exteral
+       interrupts.
+
+   Example:
+       ucc_pin@01 {
+               linux,phandle = <140001>;
+               pio-map = <
+               /* port  pin  dir  open_drain  assignment  has_irq */
+                       0  3  1  0  1  0        /* TxD0 */
+                       0  4  1  0  1  0        /* TxD1 */
+                       0  5  1  0  1  0        /* TxD2 */
+                       0  6  1  0  1  0        /* TxD3 */
+                       1  6  1  0  3  0        /* TxD4 */
+                       1  7  1  0  1  0        /* TxD5 */
+                       1  9  1  0  2  0        /* TxD6 */
+                       1  a  1  0  2  0        /* TxD7 */
+                       0  9  2  0  1  0        /* RxD0 */
+                       0  a  2  0  1  0        /* RxD1 */
+                       0  b  2  0  1  0        /* RxD2 */
+                       0  c  2  0  1  0        /* RxD3 */
+                       0  d  2  0  1  0        /* RxD4 */
+                       1  1  2  0  2  0        /* RxD5 */
+                       1  0  2  0  2  0        /* RxD6 */
+                       1  4  2  0  2  0        /* RxD7 */
+                       0  7  1  0  1  0        /* TX_EN */
+                       0  8  1  0  1  0        /* TX_ER */
+                       0  f  2  0  1  0        /* RX_DV */
+                       0  10 2  0  1  0        /* RX_ER */
+                       0  0  2  0  1  0        /* RX_CLK */
+                       2  9  1  0  3  0        /* GTX_CLK - CLK10 */
+                       2  8  2  0  1  0>;      /* GTX125 - CLK9 */
+       };
+
+   vii) Multi-User RAM (MURAM)
+
+   Required properties:
+   - device_type : should be "muram".
+   - mode : the could be "host" or "slave".
+   - ranges : Should be defined as specified in 1) to describe the
+      translation of MURAM addresses.
+   - data-only : sub-node which defines the address area under MURAM
+      bus that can be allocated as data/parameter
+
+   Example:
+
+       muram@10000 {
+               device_type = "muram";
+               ranges = <0 00010000 0000c000>;
+
+               data-only@0{
+                       reg = <0 c000>;
+               };
+       };
 
    More devices will be defined as this spec matures.
 
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 669a09aa5bb463934d96c25a76dc0346b8611fe8..126e59d935cd2348f162fc06aefe2538478584c4 100644 (file)
@@ -16,7 +16,7 @@
  15 -> DViCO FusionHDTV DVB-T1                             [18ac:db00]
  16 -> KWorld LTV883RF
  17 -> DViCO FusionHDTV 3 Gold-Q                           [18ac:d810,18ac:d800]
- 18 -> Hauppauge Nova-T DVB-T                              [0070:9002,0070:9001]
+ 18 -> Hauppauge Nova-T DVB-T                              [0070:9002,0070:9001,0070:9000]
  19 -> Conexant DVB-T reference design                     [14f1:0187]
  20 -> Provideo PV259                                      [1540:2580]
  21 -> DViCO FusionHDTV DVB-T Plus                         [18ac:db10,18ac:db11]
@@ -41,7 +41,7 @@
  40 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid                [0070:9400,0070:9402]
  41 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile)  [0070:9800,0070:9802]
  42 -> digitalnow DNTV Live! DVB-T Pro                     [1822:0025,1822:0019]
- 43 -> KWorld/VStream XPert DVB-T with cx22702             [17de:08a1]
+ 43 -> KWorld/VStream XPert DVB-T with cx22702             [17de:08a1,12ab:2300]
  44 -> DViCO FusionHDTV DVB-T Dual Digital                 [18ac:db50,18ac:db54]
  45 -> KWorld HardwareMpegTV XPert                         [17de:0840]
  46 -> DViCO FusionHDTV DVB-T Hybrid                       [18ac:db40,18ac:db44]
index 94cf695b1378ce8f79dd763448d3303909b76d19..6fb82ac3bef09e6c40aa48c76b37f42d21ad9c5c 100644 (file)
@@ -97,3 +97,4 @@
  96 -> Medion Md8800 Quadro                     [16be:0007,16be:0008]
  97 -> LifeView FlyDVB-S /Acorp TV134DS         [5168:0300,4e42:0300]
  98 -> Proteus Pro 2309                         [0919:2003]
+ 99 -> AVerMedia TV Hybrid A16AR                [1461:2c00]
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 7c238e4fce5c40420aba2b851f597911e07529ee..17becb9b1a96b5ea066f8caa82e34914bd188051 100644 (file)
@@ -144,11 +144,9 @@ L: netdev@vger.kernel.org
 S:     Maintained
 
 8250/16?50 (AND CLONE UARTS) SERIAL DRIVER
-P:     Russell King
-M:     rmk+serial@arm.linux.org.uk
 L:     linux-serial@vger.kernel.org
 W:     http://serial.sourceforge.net
-S:     Maintained
+S:     Orphan
 
 8390 NETWORK DRIVERS [WD80x3/SMC-ELITE, SMC-ULTRA, NE2000, 3C503, etc.]
 P:     Paul Gortmaker
@@ -989,6 +987,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
@@ -1913,11 +1918,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
@@ -2004,9 +2004,7 @@ W:        http://www.atnf.csiro.au/~rgooch/linux/kernel-patches.html
 S:     Maintained
 
 MULTIMEDIA CARD (MMC) SUBSYSTEM
-P:     Russell King
-M:     rmk+mmc@arm.linux.org.uk
-S:     Maintained
+S:     Orphan
 
 MULTISOUND SOUND DRIVER
 P:     Andrew Veliath
@@ -2456,6 +2454,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
@@ -2729,14 +2740,6 @@ M:       chrisw@sous-sol.org
 L:     stable@kernel.org
 S:     Maintained
 
-STABLE BRANCH:
-P:     Greg Kroah-Hartman
-M:     greg@kroah.com
-P:     Chris Wright
-M:     chrisw@sous-sol.org
-L:     stable@kernel.org
-S:     Maintained
-
 TPM DEVICE DRIVER
 P:     Kylene Hall
 M:     kjhall@us.ibm.com
@@ -2843,17 +2846,13 @@ P:      Paul Mundt
 M:     lethal@linux-sh.org
 L:     linuxsh-dev@lists.sourceforge.net (subscribers-only)
 W:     http://www.linux-sh.org
-W:     http://www.m17n.org/linux-sh/
 S:     Maintained
 
 SUPERH64 (sh64)
 P:     Paul Mundt
 M:     lethal@linux-sh.org
-P:     Richard Curnow
-M:     rc@rc0.org.uk
 L:     linuxsh-shmedia-dev@lists.sourceforge.net
 W:     http://www.linux-sh.org
-W:     http://www.rc0.org.uk/sh64
 S:     Maintained
 
 SUN3/3X
@@ -2888,6 +2887,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
@@ -3411,12 +3415,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 f042cc42b00fc531f7c8e6528aae05002a72b172..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.
@@ -36,7 +36,6 @@
 #include <asm/cacheflush.h>
 #include <asm/vga.h>
 
-#define __KERNEL_SYSCALLS__
 #include <asm/unistd.h>
 
 extern struct hwrpb_struct *hwrpb;
@@ -116,7 +115,7 @@ EXPORT_SYMBOL(sys_dup);
 EXPORT_SYMBOL(sys_exit);
 EXPORT_SYMBOL(sys_write);
 EXPORT_SYMBOL(sys_lseek);
-EXPORT_SYMBOL(execve);
+EXPORT_SYMBOL(kernel_execve);
 EXPORT_SYMBOL(sys_setsid);
 EXPORT_SYMBOL(sys_wait4);
 
index 01ecd09d4a64c42be3a6872d6f068e0492db03d9..c95e95e1ab0423b2664e8359a32ff2da0d13372d 100644 (file)
@@ -655,12 +655,12 @@ kernel_thread:
 .end kernel_thread
 
 /*
- * execve(path, argv, envp)
+ * kernel_execve(path, argv, envp)
  */
        .align  4
-       .globl  execve
-       .ent    execve
-execve:
+       .globl  kernel_execve
+       .ent    kernel_execve
+kernel_execve:
        /* We can be called from a module.  */
        ldgp    $gp, 0($27)
        lda     $sp, -(32+SIZEOF_PT_REGS+8)($sp)
@@ -704,7 +704,7 @@ execve:
 
 1:     lda     $sp, 32+SIZEOF_PT_REGS+8($sp)
        ret
-.end execve
+.end kernel_execve
 
 \f
 /*
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 73c7622b529755d2d42def44da80ee335c631df7..ad61736519950e72debd8fa691a9c59181a361a8 100644 (file)
@@ -111,22 +111,26 @@ struct osf_dirent_callback {
 
 static int
 osf_filldir(void *__buf, const char *name, int namlen, loff_t offset,
-           ino_t ino, unsigned int d_type)
+           u64 ino, unsigned int d_type)
 {
        struct osf_dirent __user *dirent;
        struct osf_dirent_callback *buf = (struct osf_dirent_callback *) __buf;
        unsigned int reclen = ROUND_UP(NAME_OFFSET + namlen + 1);
+       unsigned int d_ino;
 
        buf->error = -EINVAL;   /* only used if we fail */
        if (reclen > buf->count)
                return -EINVAL;
+       d_ino = ino;
+       if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+               return -EOVERFLOW;
        if (buf->basep) {
                if (put_user(offset, buf->basep))
                        return -EFAULT;
                buf->basep = NULL;
        }
        dirent = buf->dirent;
-       put_user(ino, &dirent->d_ino);
+       put_user(d_ino, &dirent->d_ino);
        put_user(namlen, &dirent->d_namlen);
        put_user(reclen, &dirent->d_reclen);
        if (copy_to_user(dirent->d_name, name, namlen) ||
@@ -402,15 +406,15 @@ osf_utsname(char __user *name)
 
        down_read(&uts_sem);
        error = -EFAULT;
-       if (copy_to_user(name + 0, system_utsname.sysname, 32))
+       if (copy_to_user(name + 0, utsname()->sysname, 32))
                goto out;
-       if (copy_to_user(name + 32, system_utsname.nodename, 32))
+       if (copy_to_user(name + 32, utsname()->nodename, 32))
                goto out;
-       if (copy_to_user(name + 64, system_utsname.release, 32))
+       if (copy_to_user(name + 64, utsname()->release, 32))
                goto out;
-       if (copy_to_user(name + 96, system_utsname.version, 32))
+       if (copy_to_user(name + 96, utsname()->version, 32))
                goto out;
-       if (copy_to_user(name + 128, system_utsname.machine, 32))
+       if (copy_to_user(name + 128, utsname()->machine, 32))
                goto out;
 
        error = 0;
@@ -449,8 +453,8 @@ osf_getdomainname(char __user *name, int namelen)
 
        down_read(&uts_sem);
        for (i = 0; i < len; ++i) {
-               __put_user(system_utsname.domainname[i], name + i);
-               if (system_utsname.domainname[i] == '\0')
+               __put_user(utsname()->domainname[i], name + i);
+               if (utsname()->domainname[i] == '\0')
                        break;
        }
        up_read(&uts_sem);
@@ -607,12 +611,12 @@ osf_sigstack(struct sigstack __user *uss, struct sigstack __user *uoss)
 asmlinkage long
 osf_sysinfo(int command, char __user *buf, long count)
 {
-       static char * sysinfo_table[] = {
-               system_utsname.sysname,
-               system_utsname.nodename,
-               system_utsname.release,
-               system_utsname.version,
-               system_utsname.machine,
+       char *sysinfo_table[] = {
+               utsname()->sysname,
+               utsname()->nodename,
+               utsname()->release,
+               utsname()->version,
+               utsname()->machine,
                "alpha",        /* instruction set architecture */
                "dummy",        /* hardware serial number */
                "dummy",        /* hardware manufacturer */
index 9d7dff27f81562e986064ff55d68d045cd8ca5fb..75692320386080c25a730f1e78779b1851f75926 100644 (file)
@@ -229,7 +229,7 @@ srmcons_close(struct tty_struct *tty, struct file *filp)
 
 static struct tty_driver *srmcons_driver;
 
-static struct tty_operations srmcons_ops = {
+static const struct tty_operations srmcons_ops = {
        .open           = srmcons_open,
        .close          = srmcons_close,
        .write          = srmcons_write,
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 e5ab51b9cceb1bdfd155c9824ba6364d21cc1977..2568d311be215a7301bc752f4813a9e64e866999 100644 (file)
@@ -237,7 +237,8 @@ not_relocated:      mov     r0, #0
  */
                cmp     r4, r2
                bhs     wont_overwrite
-               add     r0, r4, #4096*1024      @ 4MB largest kernel size
+               sub     r3, sp, r5              @ > compressed kernel size
+               add     r0, r4, r3, lsl #2      @ allow for 4x expansion
                cmp     r0, r5
                bls     wont_overwrite
 
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 5365d4e5949e5bd8275bac811e38ea3df8c77f0f..ebc3e74a79476ebde1171351ac33dd5f9a23d319 100644 (file)
@@ -234,18 +234,18 @@ __create_page_tables:
 
        /*
         * Now setup the pagetables for our kernel direct
-        * mapped region.  We round TEXTADDR down to the
-        * nearest megabyte boundary.  It is assumed that
-        * the kernel fits within 4 contigous 1MB sections.
+        * mapped region.
         */
        add     r0, r4,  #(TEXTADDR & 0xff000000) >> 18 @ start of kernel
        str     r3, [r0, #(TEXTADDR & 0x00f00000) >> 18]!
-       add     r3, r3, #1 << 20
-       str     r3, [r0, #4]!                   @ KERNEL + 1MB
-       add     r3, r3, #1 << 20
-       str     r3, [r0, #4]!                   @ KERNEL + 2MB
-       add     r3, r3, #1 << 20
-       str     r3, [r0, #4]                    @ KERNEL + 3MB
+
+       ldr     r6, =(_end - PAGE_OFFSET - 1)   @ r6 = number of sections
+       mov     r6, r6, lsr #20                 @ needed for kernel minus 1
+
+1:     add     r3, r3, #1 << 20
+       str     r3, [r0, #4]!
+       subs    r6, r6, #1
+       bgt     1b
 
        /*
         * Then map first 1MB of ram in case it contains our boot params.
index 0a722e77c1438af559c9068399a3ec251862c2d8..6bbd93dd186a74f43ca3bbae43cac88e90c63f4c 100644 (file)
@@ -348,7 +348,7 @@ static void __init setup_processor(void)
               cpu_name, processor_id, (int)processor_id & 15,
               proc_arch[cpu_architecture()], cr_alignment);
 
-       sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS);
+       sprintf(init_utsname()->machine, "%s%c", list->arch_name, ENDIANNESS);
        sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
        elf_hwcap = list->elf_hwcap;
 #ifndef CONFIG_ARM_THUMB
index 68e9634d260a74c8a1d21d93db7a2421fa376859..421329f5e18e6ea0a8e336b4a32543622f1c0895 100644 (file)
@@ -36,7 +36,9 @@
  * The online bitmask indicates that the CPU is up and running.
  */
 cpumask_t cpu_possible_map;
+EXPORT_SYMBOL(cpu_possible_map);
 cpumask_t cpu_online_map;
+EXPORT_SYMBOL(cpu_online_map);
 
 /*
  * as from 2.5, kernels no longer have an init_tasks structure
index 8170af4714393ed39946682302a16ef229dfb838..00c18d35913cb2c9a6da852fba86d67efa9fd5a4 100644 (file)
@@ -279,7 +279,7 @@ out:
        return error;
 }
 
-long execve(const char *filename, char **argv, char **envp)
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
 {
        struct pt_regs regs;
        int ret;
@@ -317,7 +317,7 @@ long execve(const char *filename, char **argv, char **envp)
  out:
        return ret;
 }
-EXPORT_SYMBOL(execve);
+EXPORT_SYMBOL(kernel_execve);
 
 /*
  * Since loff_t is a 64 bit type we avoid a lot of ABI hastle
index bfefdaa8f794b077ff30115f24984243adc715eb..fa958e9d6ddd0c5e1712e15302a0a34bd21c49c2 100644 (file)
@@ -44,10 +44,40 @@ static struct platform_device edb9315a_flash = {
        .resource       = &edb9315a_flash_resource,
 };
 
+static struct ep93xx_eth_data edb9315a_eth_data = {
+       .phy_id                 = 1,
+};
+
+static struct resource edb9315a_eth_resource[] = {
+       {
+               .start  = EP93XX_ETHERNET_PHYS_BASE,
+               .end    = EP93XX_ETHERNET_PHYS_BASE + 0xffff,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = IRQ_EP93XX_ETHERNET,
+               .end    = IRQ_EP93XX_ETHERNET,
+               .flags  = IORESOURCE_IRQ,
+       }
+};
+
+static struct platform_device edb9315a_eth_device = {
+       .name           = "ep93xx-eth",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &edb9315a_eth_data,
+       },
+       .num_resources  = 2,
+       .resource       = edb9315a_eth_resource,
+};
+
 static void __init edb9315a_init_machine(void)
 {
        ep93xx_init_devices();
        platform_device_register(&edb9315a_flash);
+
+       memcpy(edb9315a_eth_data.dev_addr,
+               (void *)(EP93XX_ETHERNET_BASE + 0x50), 6);
+       platform_device_register(&edb9315a_eth_device);
 }
 
 MACHINE_START(EDB9315A, "Cirrus Logic EDB9315A Evaluation Board")
index e760fd4f36559e3e26418c03ecb3c1b9774604cf..694590a451c17710ff8f2aec1f718dc4e25d609b 100644 (file)
@@ -43,10 +43,37 @@ static struct platform_device gesbc9312_flash = {
        .resource       = &gesbc9312_flash_resource,
 };
 
+static struct ep93xx_eth_data gesbc9312_eth_data = {
+       .phy_id                 = 1,
+};
+
+static struct resource gesbc9312_eth_resource[] = {
+       {
+               .start  = EP93XX_ETHERNET_PHYS_BASE,
+               .end    = EP93XX_ETHERNET_PHYS_BASE + 0xffff,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = IRQ_EP93XX_ETHERNET,
+               .end    = IRQ_EP93XX_ETHERNET,
+               .flags  = IORESOURCE_IRQ,
+       }
+};
+
+static struct platform_device gesbc9312_eth_device = {
+       .name           = "ep93xx-eth",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &gesbc9312_eth_data,
+       },
+       .num_resources  = 2,
+       .resource       = gesbc9312_eth_resource,
+};
+
 static void __init gesbc9312_init_machine(void)
 {
        ep93xx_init_devices();
        platform_device_register(&gesbc9312_flash);
+       platform_device_register(&gesbc9312_eth_device);
 }
 
 MACHINE_START(GESBC9312, "Glomation GESBC-9312-sx")
index df315f2e9bebe9219474f6845fd4794c7466abe2..3a4bf90ba8326f29f4e917336a10efaf712ae485 100644 (file)
@@ -157,12 +157,42 @@ static struct platform_device ts72xx_rtc_device = {
        .num_resources          = 0,
 };
 
+static struct ep93xx_eth_data ts72xx_eth_data = {
+       .phy_id                 = 1,
+};
+
+static struct resource ts72xx_eth_resource[] = {
+       {
+               .start  = EP93XX_ETHERNET_PHYS_BASE,
+               .end    = EP93XX_ETHERNET_PHYS_BASE + 0xffff,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = IRQ_EP93XX_ETHERNET,
+               .end    = IRQ_EP93XX_ETHERNET,
+               .flags  = IORESOURCE_IRQ,
+       }
+};
+
+static struct platform_device ts72xx_eth_device = {
+       .name           = "ep93xx-eth",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &ts72xx_eth_data,
+       },
+       .num_resources  = 2,
+       .resource       = ts72xx_eth_resource,
+};
+
 static void __init ts72xx_init_machine(void)
 {
        ep93xx_init_devices();
        if (board_is_ts7200())
                platform_device_register(&ts72xx_flash);
        platform_device_register(&ts72xx_rtc_device);
+
+       memcpy(ts72xx_eth_data.dev_addr,
+               (void *)(EP93XX_ETHERNET_BASE + 0x50), 6);
+       platform_device_register(&ts72xx_eth_device);
 }
 
 MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC")
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 f582ed2ec43c615cbbc10c8812b3b423ef7f2096..daa8d3d98eff13b7d33927d7a8218bdc021d4bc7 100644 (file)
@@ -735,6 +735,16 @@ static struct clk uart6_ck = {
        .enable_reg = UARTCLKCTRL_REG,
 };
 
+static struct clk wdt_ck = {
+       .name = "wdt_ck",
+       .parent = &per_ck,
+       .flags = NEEDS_INITIALIZATION,
+       .round_rate = &on_off_round_rate,
+       .set_rate = &on_off_set_rate,
+       .enable_shift = 0,
+       .enable_reg = TIMCLKCTRL_REG,
+};
+
 /* These clocks are visible outside this module
  * and can be initialized
  */
@@ -765,6 +775,7 @@ static struct clk *onchip_clks[] = {
        &uart4_ck,
        &uart5_ck,
        &uart6_ck,
+       &wdt_ck,
 };
 
 static int local_clk_enable(struct clk *clk)
index 6dbcaf114ad782a00907b15672f9ae60aff0dfea..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
  *
@@ -431,10 +431,10 @@ struct platform_device corgifb_device = {
 
 #include <asm/arch/pxafb.h>
 
-void spitz_lcd_power(int on)
+void spitz_lcd_power(int on, struct fb_var_screeninfo *var)
 {
        if (on)
-               lcdtg_hw_init(480);
+               lcdtg_hw_init(var->xres);
        else
                lcdtg_suspend();
 }
index 5efa84749f374fae50ade0adfcb67c5b8bacf494..45fb2c3bcf828f3812adf0b95675d77256487c05 100644 (file)
@@ -204,13 +204,6 @@ static struct platform_device udc_device = {
        }
 };
 
-static struct pxafb_mach_info pxa_fb_info;
-
-void __init set_pxa_fb_info(struct pxafb_mach_info *hard_pxa_fb_info)
-{
-       memcpy(&pxa_fb_info,hard_pxa_fb_info,sizeof(struct pxafb_mach_info));
-}
-
 static struct resource pxafb_resources[] = {
        [0] = {
                .start  = 0x44000000,
@@ -230,7 +223,6 @@ static struct platform_device pxafb_device = {
        .name           = "pxa2xx-fb",
        .id             = -1,
        .dev            = {
-               .platform_data  = &pxa_fb_info,
                .dma_mask       = &fb_dma_mask,
                .coherent_dma_mask = 0xffffffff,
        },
@@ -238,6 +230,11 @@ static struct platform_device pxafb_device = {
        .resource       = pxafb_resources,
 };
 
+void __init set_pxa_fb_info(struct pxafb_mach_info *info)
+{
+       pxafb_device.dev.platform_data = info;
+}
+
 void __init set_pxa_fb_parent(struct device *parent_dev)
 {
        pxafb_device.dev.parent = parent_dev;
index 6914d22bc20fbfb0b19c8eba67f48e0e85ef83ad..3e4b0ab71c66bbe40530ef03935d29126b3942e8 100644 (file)
@@ -82,7 +82,7 @@ static void idp_vlcd(int on)
        }
 }
 
-static void idp_lcd_power(int on)
+static void idp_lcd_power(int on, struct fb_var_screeninfo *var)
 {
        if (on) {
                IDP_CPLD_LCD |= (1<<0);
@@ -99,7 +99,7 @@ static void idp_lcd_power(int on)
        idp_vlcd(on);
 }
 
-static struct pxafb_mach_info sharp_lm8v31 __initdata = {
+static struct pxafb_mode_info sharp_lm8v31_mode = {
        .pixclock       = 270000,
        .xres           = 640,
        .yres           = 480,
@@ -112,6 +112,11 @@ static struct pxafb_mach_info sharp_lm8v31 __initdata = {
        .lower_margin   = 0,
        .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
        .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info sharp_lm8v31 = {
+       .modes          = &sharp_lm8v31_mode,
+       .num_modes      = 1,
        .cmap_inverse   = 0,
        .cmap_static    = 0,
        .lccr0          = LCCR0_SDS,
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 12479ae26db2addc8c4bcd5f1a11a40d563f24e4..eff2a91b2565ee8b46d3673c6bbe5d12759e2c1f 100644 (file)
@@ -248,7 +248,7 @@ static void lpd270_backlight_power(int on)
 }
 
 /* 5.7" TFT QVGA (LoLo display number 1) */
-static struct pxafb_mach_info sharp_lq057q3dc02 __initdata = {
+static struct pxafb_mode_info sharp_lq057q3dc02_mode = {
        .pixclock               = 150000,
        .xres                   = 320,
        .yres                   = 240,
@@ -260,13 +260,18 @@ static struct pxafb_mach_info sharp_lq057q3dc02 __initdata = {
        .upper_margin           = 0x08,
        .lower_margin           = 0x14,
        .sync                   = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info sharp_lq057q3dc02 = {
+       .modes                  = &sharp_lq057q3dc02_mode,
+       .num_modes              = 1,
        .lccr0                  = 0x07800080,
        .lccr3                  = 0x00400000,
        .pxafb_backlight_power  = lpd270_backlight_power,
 };
 
 /* 12.1" TFT SVGA (LoLo display number 2) */
-static struct pxafb_mach_info sharp_lq121s1dg31 __initdata = {
+static struct pxafb_mode_info sharp_lq121s1dg31_mode = {
        .pixclock               = 50000,
        .xres                   = 800,
        .yres                   = 600,
@@ -278,13 +283,18 @@ static struct pxafb_mach_info sharp_lq121s1dg31 __initdata = {
        .upper_margin           = 0x14,
        .lower_margin           = 0x0a,
        .sync                   = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info sharp_lq121s1dg31 = {
+       .modes                  = &sharp_lq121s1dg31_mode,
+       .num_modes              = 1,
        .lccr0                  = 0x07800080,
        .lccr3                  = 0x00400000,
        .pxafb_backlight_power  = lpd270_backlight_power,
 };
 
 /* 3.6" TFT QVGA (LoLo display number 3) */
-static struct pxafb_mach_info sharp_lq036q1da01 __initdata = {
+static struct pxafb_mode_info sharp_lq036q1da01_mode = {
        .pixclock               = 150000,
        .xres                   = 320,
        .yres                   = 240,
@@ -296,13 +306,18 @@ static struct pxafb_mach_info sharp_lq036q1da01 __initdata = {
        .upper_margin           = 0x03,
        .lower_margin           = 0x03,
        .sync                   = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info sharp_lq036q1da01 = {
+       .modes                  = &sharp_lq036q1da01_mode,
+       .num_modes              = 1,
        .lccr0                  = 0x07800080,
        .lccr3                  = 0x00400000,
        .pxafb_backlight_power  = lpd270_backlight_power,
 };
 
 /* 6.4" TFT VGA (LoLo display number 5) */
-static struct pxafb_mach_info sharp_lq64d343 __initdata = {
+static struct pxafb_mode_info sharp_lq64d343_mode = {
        .pixclock               = 25000,
        .xres                   = 640,
        .yres                   = 480,
@@ -314,13 +329,18 @@ static struct pxafb_mach_info sharp_lq64d343 __initdata = {
        .upper_margin           = 0x22,
        .lower_margin           = 0x00,
        .sync                   = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info sharp_lq64d343 = {
+       .modes                  = &sharp_lq64d343_mode,
+       .num_modes              = 1,
        .lccr0                  = 0x07800080,
        .lccr3                  = 0x00400000,
        .pxafb_backlight_power  = lpd270_backlight_power,
 };
 
 /* 10.4" TFT VGA (LoLo display number 7) */
-static struct pxafb_mach_info sharp_lq10d368 __initdata = {
+static struct pxafb_mode_info sharp_lq10d368_mode = {
        .pixclock               = 25000,
        .xres                   = 640,
        .yres                   = 480,
@@ -332,13 +352,18 @@ static struct pxafb_mach_info sharp_lq10d368 __initdata = {
        .upper_margin           = 0x22,
        .lower_margin           = 0x00,
        .sync                   = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info sharp_lq10d368 = {
+       .modes                  = &sharp_lq10d368_mode,
+       .num_modes              = 1,
        .lccr0                  = 0x07800080,
        .lccr3                  = 0x00400000,
        .pxafb_backlight_power  = lpd270_backlight_power,
 };
 
 /* 3.5" TFT QVGA (LoLo display number 8) */
-static struct pxafb_mach_info sharp_lq035q7db02_20 __initdata = {
+static struct pxafb_mode_info sharp_lq035q7db02_20_mode = {
        .pixclock               = 150000,
        .xres                   = 240,
        .yres                   = 320,
@@ -350,6 +375,11 @@ static struct pxafb_mach_info sharp_lq035q7db02_20 __initdata = {
        .upper_margin           = 0x05,
        .lower_margin           = 0x14,
        .sync                   = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info sharp_lq035q7db02_20 = {
+       .modes                  = &sharp_lq035q7db02_20_mode,
+       .num_modes              = 1,
        .lccr0                  = 0x07800080,
        .lccr3                  = 0x00400000,
        .pxafb_backlight_power  = lpd270_backlight_power,
index 83ff5cee64d935d27396564f78721ff90b2d582b..157cf47cbe6655e239cb7a0c78abe15b4df88788 100644 (file)
@@ -352,7 +352,7 @@ static struct platform_device *devices[] __initdata = {
        &pxa_ssp,
 };
 
-static struct pxafb_mach_info sharp_lm8v31 __initdata = {
+static struct pxafb_mode_info sharp_lm8v31_mode = {
        .pixclock       = 270000,
        .xres           = 640,
        .yres           = 480,
@@ -365,6 +365,11 @@ static struct pxafb_mach_info sharp_lm8v31 __initdata = {
        .lower_margin   = 0,
        .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
        .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info sharp_lm8v31 = {
+       .modes          = &sharp_lm8v31_mode,
+       .num_modes      = 1,
        .cmap_inverse   = 0,
        .cmap_static    = 0,
        .lccr0          = LCCR0_SDS,
index a7e9b96f258a4b34e9a209dca6b2f7ddb69e8228..7ba0447d6fa3dfbbb160f3c98e88daa97565dba9 100644 (file)
@@ -279,7 +279,7 @@ static void mainstone_backlight_power(int on)
        }
 }
 
-static struct pxafb_mach_info toshiba_ltm04c380k __initdata = {
+static struct pxafb_mode_info toshiba_ltm04c380k_mode = {
        .pixclock               = 50000,
        .xres                   = 640,
        .yres                   = 480,
@@ -291,12 +291,9 @@ static struct pxafb_mach_info toshiba_ltm04c380k __initdata = {
        .upper_margin           = 0,
        .lower_margin           = 0,
        .sync                   = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
-       .lccr0                  = LCCR0_Act,
-       .lccr3                  = LCCR3_PCP,
-       .pxafb_backlight_power  = mainstone_backlight_power,
 };
 
-static struct pxafb_mach_info toshiba_ltm035a776c __initdata = {
+static struct pxafb_mode_info toshiba_ltm035a776c_mode = {
        .pixclock               = 110000,
        .xres                   = 240,
        .yres                   = 320,
@@ -308,6 +305,10 @@ static struct pxafb_mach_info toshiba_ltm035a776c __initdata = {
        .upper_margin           = 1,
        .lower_margin           = 10,
        .sync                   = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info mainstone_pxafb_info = {
+       .num_modes              = 1,
        .lccr0                  = LCCR0_Act,
        .lccr3                  = LCCR3_PCP,
        .pxafb_backlight_power  = mainstone_backlight_power,
@@ -448,9 +449,11 @@ static void __init mainstone_init(void)
        /* reading Mainstone's "Virtual Configuration Register"
           might be handy to select LCD type here */
        if (0)
-               set_pxa_fb_info(&toshiba_ltm04c380k);
+               mainstone_pxafb_info.modes = &toshiba_ltm04c380k_mode;
        else
-               set_pxa_fb_info(&toshiba_ltm035a776c);
+               mainstone_pxafb_info.modes = &toshiba_ltm035a776c_mode;
+
+       set_pxa_fb_info(&mainstone_pxafb_info);
 
        pxa_set_mci_info(&mainstone_mci_platform_data);
        pxa_set_ficp_info(&mainstone_ficp_platform_data);
index 6dbff6d9480172fe0f9209f32587e03a7f56cc26..5e8c098ca13986125b15927bc9b8d2dc0eff1c52 100644 (file)
@@ -296,27 +296,25 @@ static struct pxa2xx_udc_mach_info udc_info __initdata = {
 
 
 /* PXAFB device */
-static struct pxafb_mach_info poodle_fb_info __initdata = {
+static struct pxafb_mode_info poodle_fb_mode = {
        .pixclock       = 144700,
-
        .xres           = 320,
        .yres           = 240,
        .bpp            = 16,
-
        .hsync_len      = 7,
        .left_margin    = 11,
        .right_margin   = 30,
-
        .vsync_len      = 2,
        .upper_margin   = 2,
        .lower_margin   = 0,
        .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
 
+static struct pxafb_mach_info poodle_fb_info = {
+       .modes          = &poodle_fb_mode,
+       .num_modes      = 1,
        .lccr0          = LCCR0_Act | LCCR0_Sngl | LCCR0_Color,
        .lccr3          = 0,
-
-       .pxafb_backlight_power  = NULL,
-       .pxafb_lcd_power        = NULL,
 };
 
 static struct platform_device *devices[] __initdata = {
index 1c32a9310dc27abe5aa43d54d24a7bfdc2a50b62..401cdb850fbc2f014eec92a2a307290b99425eca 100644 (file)
@@ -407,21 +407,42 @@ static struct pxaficp_platform_data spitz_ficp_platform_data = {
 /*
  * Spitz PXA Framebuffer
  */
-static struct pxafb_mach_info spitz_pxafb_info __initdata = {
-        .pixclock       = 19231,
-        .xres           = 480,
-        .yres           = 640,
-        .bpp            = 16,
-        .hsync_len      = 40,
-        .left_margin    = 46,
-        .right_margin   = 125,
-        .vsync_len      = 3,
-        .upper_margin   = 1,
-        .lower_margin   = 0,
-        .sync           = 0,
-        .lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act | LCCR0_LDDALT | LCCR0_OUC | LCCR0_CMDIM | LCCR0_RDSTM,
-        .lccr3          = LCCR3_PixRsEdg | LCCR3_OutEnH,
-        .pxafb_lcd_power = spitz_lcd_power,
+
+static struct pxafb_mode_info spitz_pxafb_modes[] = {
+{
+       .pixclock       = 19231,
+       .xres           = 480,
+       .yres           = 640,
+       .bpp            = 16,
+       .hsync_len      = 40,
+       .left_margin    = 46,
+       .right_margin   = 125,
+       .vsync_len      = 3,
+       .upper_margin   = 1,
+       .lower_margin   = 0,
+       .sync           = 0,
+},{
+       .pixclock       = 134617,
+       .xres           = 240,
+       .yres           = 320,
+       .bpp            = 16,
+       .hsync_len      = 20,
+       .left_margin    = 20,
+       .right_margin   = 46,
+       .vsync_len      = 2,
+       .upper_margin   = 1,
+       .lower_margin   = 0,
+       .sync           = 0,
+},
+};
+
+static struct pxafb_mach_info spitz_pxafb_info = {
+       .modes          = &spitz_pxafb_modes[0],
+       .num_modes      = 2,
+       .fixed_modes    = 1,
+       .lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act | LCCR0_LDDALT | LCCR0_OUC | LCCR0_CMDIM | LCCR0_RDSTM,
+       .lccr3          = LCCR3_PixRsEdg | LCCR3_OutEnH,
+       .pxafb_lcd_power = spitz_lcd_power,
 };
 
 
index 7c3007df1bd6e22be0c009dd796b5cf69bb89f11..910571e9a190cba0597219ce523c7c97a7525e7d 100644 (file)
@@ -368,7 +368,7 @@ static struct map_desc trizeps4_io_desc[] __initdata = {
        }
 };
 
-static struct pxafb_mach_info sharp_lcd __initdata = {
+static struct pxafb_mode_info sharp_lcd_mode = {
     .pixclock          = 78000,
     .xres              = 640,
     .yres              = 480,
@@ -381,6 +381,11 @@ static struct pxafb_mach_info sharp_lcd __initdata = {
     .lower_margin      = 0,
     .sync              = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
     .cmap_greyscale    = 0,
+};
+
+static struct pxafb_mach_info sharp_lcd = {
+    .modes             = &sharp_lcd_mode,
+    .num_modes = 1,
     .cmap_inverse      = 0,
     .cmap_static       = 0,
     .lccr0             = LCCR0_Color | LCCR0_Pas | LCCR0_Dual,
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 e566cbe4b222cd93186d6d06dd7b279fbbae4563..f866bf6b97d4f3dc810eeeaa140f9ecf2e10d965 100644 (file)
@@ -27,7 +27,7 @@
 
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
-extern void _stext, __data_start, _end;
+extern void _stext, _etext, __data_start, _end;
 extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
 
 /*
index 6576143f25598253bba9e5d8701bdb44d8bd4234..726ad2b3b435f25740790840f431988ea0f3ec99 100644 (file)
@@ -33,9 +33,6 @@
 #define PMU_CNT64      0x008   /* Make CCNT count every 64th cycle */
 
 /* TODO do runtime detection */
-#ifdef CONFIG_ARCH_IOP310
-#define XSCALE_PMU_IRQ  IRQ_XS80200_PMU
-#endif
 #ifdef CONFIG_ARCH_IOP32X
 #define XSCALE_PMU_IRQ  IRQ_IOP32X_CORE_PMU
 #endif
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 ab5e9503bae5423132a8a2388bd2ce89ebfd2a47..0221ba3bc799bcef222032a5545013bb91a286fe 100644 (file)
@@ -198,8 +198,10 @@ u32 vfp_single_normaliseround(int sd, struct vfp_single *vs, u32 fpscr, u32 exce
        vfp_single_dump("pack: final", vs);
        {
                s32 d = vfp_single_pack(vs);
+#ifdef DEBUG
                pr_debug("VFP: %s: d(s%d)=%08x exceptions=%08x\n", func,
                         sd, d, exceptions);
+#endif
                vfp_put_float(d, sd);
        }
 
index e7eb070f794fbb7d7d30fbf9f6900468998fafd8..466ddb54b44ffb01bd0c1211ddaf2f6ba80fc971 100644 (file)
@@ -143,7 +143,7 @@ static void __init setup_processor(void)
 
        dump_cpu_info();
 
-       sprintf(system_utsname.machine, "%s", list->arch_name);
+       sprintf(init_utsname()->machine, "%s", list->arch_name);
        sprintf(elf_platform, "%s", list->elf_name);
        elf_hwcap = list->elf_hwcap;
 
index 85457897b8a9cb756fe983dd4ab44588c8ef4499..dc05aba58baf29f46df49c4eb1be9e6f887e102b 100644 (file)
@@ -283,7 +283,7 @@ out:
 }
 
 /* FIXME - see if this is correct for arm26 */
-long execve(const char *filename, char **argv, char **envp)
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
 {
        struct pt_regs regs;
         int ret;
@@ -320,4 +320,4 @@ long execve(const char *filename, char **argv, char **envp)
         return ret;
 }
 
-EXPORT_SYMBOL(execve);
+EXPORT_SYMBOL(kernel_execve);
index 6ec5693da4488ce938d5c507848d4b81793caa3f..8deb6003ee626afb44c14f785c25eea3b239c9f2 100644 (file)
@@ -49,3 +49,17 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
                fput(file);
        return error;
 }
+
+int kernel_execve(const char *file, char **argv, char **envp)
+{
+       register long scno asm("r8") = __NR_execve;
+       register long sc1 asm("r12") = (long)file;
+       register long sc2 asm("r11") = (long)argv;
+       register long sc3 asm("r10") = (long)envp;
+
+       asm volatile("scall"
+                    : "=r"(sc1)
+                    : "r"(scno), "0"(sc1), "r"(sc2), "r"(sc3)
+                    : "cc", "memory");
+       return sc1;
+}
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 464ecaec3bc08d8ef21878fac55bbbdf05cc6d74..2d0023f2d49bc01ade50767f8b2f9d9584034691 100644 (file)
@@ -28,6 +28,7 @@ spinlock_t cris_atomic_locks[] = { [0 ... LOCK_COUNT - 1] = SPIN_LOCK_UNLOCKED};
 
 /* CPU masks */
 cpumask_t cpu_online_map = CPU_MASK_NONE;
+EXPORT_SYMBOL(cpu_online_map);
 cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
 EXPORT_SYMBOL(phys_cpu_present_map);
 
index 7af3d5d43e43b73466212ded824b131c46ba4886..ca8b45a0fe2ed4dc8fc48cb9c0cdfdd20a5af7db 100644 (file)
@@ -160,7 +160,7 @@ setup_arch(char **cmdline_p)
        show_etrax_copyright();
 
        /* Setup utsname */
-       strcpy(system_utsname.machine, cris_machine_name);
+       strcpy(init_utsname()->machine, cris_machine_name);
 }
 
 static void *c_start(struct seq_file *m, loff_t *pos)
index f7b171b92ea2bad7ae134ea0cc5b04cc71f5d1a0..cf1c446e003ac6cad36c4a354872d0b41b2a2925 100644 (file)
@@ -86,6 +86,14 @@ config HIGHPTE
          with a lot of RAM, this can be wasteful of precious low memory.
          Setting this option will put user-space page tables in high memory.
 
+config LARGE_ALLOCS
+       bool "Allow allocating large blocks (> 1MB) of memory"
+       help
+         Allow the slab memory allocator to keep chains for very large memory
+         sizes - up to 32MB. You may need this if your system has a lot of
+         RAM, and you need to able to allocate very large contiguous chunks.
+         If unsure, say N.
+
 source "mm/Kconfig"
 
 choice
index 32db3499c4611f2f79f2ea250e48c59a1084480f..e8f73ed28b529b248d306c47f42b9b51a3394be5 100644 (file)
@@ -8,7 +8,7 @@ heads-$(CONFIG_MMU)             := head-mmu-fr451.o
 extra-y:= head.o init_task.o vmlinux.lds
 
 obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o kernel_thread.o \
-        process.o traps.o ptrace.o signal.o dma.o \
+        kernel_execve.o process.o traps.o ptrace.o signal.o dma.o \
         sys_frv.o time.o semaphore.o setup.o frv_ksyms.o \
         debug-stub.o irq.o sleep.o uaccess.o
 
diff --git a/arch/frv/kernel/kernel_execve.S b/arch/frv/kernel/kernel_execve.S
new file mode 100644 (file)
index 0000000..9b074a1
--- /dev/null
@@ -0,0 +1,33 @@
+/* in-kernel program execution
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/linkage.h>
+#include <asm/unistd.h>
+
+###############################################################################
+#
+# Do a system call from kernel instead of calling sys_execve so we end up with
+# proper pt_regs.
+#
+# int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+#
+# On entry: GR8/GR9/GR10: arguments to function
+# On return: GR8: syscall return.
+#
+###############################################################################
+       .globl          kernel_execve
+       .type           kernel_execve,@function
+kernel_execve:
+       setlos          __NR_execve,gr7
+       tira            gr0,#0
+       bralr
+
+       .size           kernel_execve,.-kernel_execve
index d96a57e5f030a93f4f57b5181d4146a6472a65d0..a8c61dac1cee29185ee234cb913a680789cbdc13 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/serial_reg.h>
 
 #include <asm/setup.h>
-#include <asm/serial.h>
 #include <asm/irq.h>
 #include <asm/sections.h>
 #include <asm/pgalloc.h>
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 0f61b7ad69abdea6661f411c1696cb3af7388424..302a2dfe634aa8df11b3bfe47669003116cd8a86 100644 (file)
@@ -25,6 +25,7 @@
 #include <asm/cachectl.h>
 #include <asm/traps.h>
 #include <asm/ipc.h>
+#include <asm/unistd.h>
 
 /*
  * sys_pipe() is the normal C calling standard for creating
@@ -280,3 +281,26 @@ asmlinkage void syscall_print(void *dummy,...)
                ((regs->pc)&0xffffff)-2,regs->orig_er0,regs->er1,regs->er2,regs->er3,regs->er0);
 }
 #endif
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+       register long res __asm__("er0");
+       register const char * _a __asm__("er1") = filename;
+       register void *_b __asm__("er2") = argv;
+       register void *_c __asm__("er3") = envp;
+       __asm__ __volatile__ ("mov.l %1,er0\n\t"
+                       "trapa  #0\n\t"
+                       : "=r" (res)
+                       : "g" (__NR_execve),
+                         "g" (_a),
+                         "g" (_b),
+                         "g" (_c)
+                       : "cc", "memory");
+       return res;
+}
+
+
index 3fd2f256f2be3402cea23aa3a93a21c0c161197a..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).
@@ -1142,7 +1142,7 @@ source "arch/i386/oprofile/Kconfig"
 
 config KPROBES
        bool "Kprobes (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && MODULES
+       depends on KALLSYMS && EXPERIMENTAL && MODULES
        help
          Kprobes allows you to trap at almost any kernel address and
          execute a callback function.  register_kprobe() establishes
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 2799baaadf45f5b7afbabbbc588a438d5308b190..d9f3e3c31f054240c790bbb461c8f261f2726487 100644 (file)
@@ -184,7 +184,16 @@ static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c, int early)
 
 static int __init x86_fxsr_setup(char * s)
 {
+       /* Tell all the other CPU's to not use it... */
        disable_x86_fxsr = 1;
+
+       /*
+        * ... and clear the bits early in the boot_cpu_data
+        * so that the bootup process doesn't try to do this
+        * either.
+        */
+       clear_bit(X86_FEATURE_FXSR, boot_cpu_data.x86_capability);
+       clear_bit(X86_FEATURE_XMM, boot_cpu_data.x86_capability);
        return 1;
 }
 __setup("nofxsr", x86_fxsr_setup);
@@ -660,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 afe6505ca0b3a78af53db084d60574540ea7361d..d98e44b16fe20fa1edbda6d0246bc95b3a49cede 100644 (file)
@@ -230,20 +230,20 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
                                      struct pt_regs *regs)
 {
        unsigned long *sara = (unsigned long *)&regs->esp;
-        struct kretprobe_instance *ri;
 
-        if ((ri = get_free_rp_inst(rp)) != NULL) {
-                ri->rp = rp;
-                ri->task = current;
+       struct kretprobe_instance *ri;
+
+       if ((ri = get_free_rp_inst(rp)) != NULL) {
+               ri->rp = rp;
+               ri->task = current;
                ri->ret_addr = (kprobe_opcode_t *) *sara;
 
                /* Replace the return addr with trampoline addr */
                *sara = (unsigned long) &kretprobe_trampoline;
-
-                add_rp_inst(ri);
-        } else {
-                rp->nmissed++;
-        }
+               add_rp_inst(ri);
+       } else {
+               rp->nmissed++;
+       }
 }
 
 /*
@@ -359,7 +359,7 @@ no_kprobe:
  void __kprobes kretprobe_trampoline_holder(void)
  {
        asm volatile ( ".global kretprobe_trampoline\n"
-                       "kretprobe_trampoline: \n"
+                       "kretprobe_trampoline: \n"
                        "       pushf\n"
                        /* skip cs, eip, orig_eax, es, ds */
                        "       subl $20, %esp\n"
@@ -395,14 +395,15 @@ no_kprobe:
  */
 fastcall void *__kprobes trampoline_handler(struct pt_regs *regs)
 {
-        struct kretprobe_instance *ri = NULL;
-        struct hlist_head *head;
-        struct hlist_node *node, *tmp;
+       struct kretprobe_instance *ri = NULL;
+       struct hlist_head *head, empty_rp;
+       struct hlist_node *node, *tmp;
        unsigned long flags, orig_ret_address = 0;
        unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
 
+       INIT_HLIST_HEAD(&empty_rp);
        spin_lock_irqsave(&kretprobe_lock, flags);
-        head = kretprobe_inst_table_head(current);
+       head = kretprobe_inst_table_head(current);
 
        /*
         * It is possible to have multiple instances associated with a given
@@ -413,14 +414,14 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs)
         * We can handle this because:
         *     - instances are always inserted at the head of the list
         *     - when multiple return probes are registered for the same
-         *       function, the first instance's ret_addr will point to the
+        *       function, the first instance's ret_addr will point to the
         *       real return address, and all the rest will point to
         *       kretprobe_trampoline
         */
        hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
-                if (ri->task != current)
+               if (ri->task != current)
                        /* another task is sharing our hash bucket */
-                        continue;
+                       continue;
 
                if (ri->rp && ri->rp->handler){
                        __get_cpu_var(current_kprobe) = &ri->rp->kp;
@@ -429,7 +430,7 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs)
                }
 
                orig_ret_address = (unsigned long)ri->ret_addr;
-               recycle_rp_inst(ri);
+               recycle_rp_inst(ri, &empty_rp);
 
                if (orig_ret_address != trampoline_address)
                        /*
@@ -444,6 +445,10 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs)
 
        spin_unlock_irqrestore(&kretprobe_lock, flags);
 
+       hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
+               hlist_del(&ri->hlist);
+               kfree(ri);
+       }
        return (void*)orig_ret_address;
 }
 
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 96cd0232e1e03ad24638a6837e024de24ecd0c79..dad02a960e03572046c2e9ced98186c64e7ca5a5 100644 (file)
@@ -297,9 +297,9 @@ void show_regs(struct pt_regs * regs)
        if (user_mode_vm(regs))
                printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
        printk(" EFLAGS: %08lx    %s  (%s %.*s)\n",
-              regs->eflags, print_tainted(), system_utsname.release,
-              (int)strcspn(system_utsname.version, " "),
-              system_utsname.version);
+              regs->eflags, print_tainted(), init_utsname()->release,
+              (int)strcspn(init_utsname()->version, " "),
+              init_utsname()->version);
        printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
                regs->eax,regs->ebx,regs->ecx,regs->edx);
        printk("ESI: %08lx EDI: %08lx EBP: %08lx",
index 0831f709f7771493d09f6e662eddd6950aeabe81..4bb8b77cd65b257b4b54a730f5c5e3cf46595f4a 100644 (file)
@@ -612,6 +612,7 @@ extern struct {
 /* which logical CPUs are on which nodes */
 cpumask_t node_2_cpu_mask[MAX_NUMNODES] __read_mostly =
                                { [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE };
+EXPORT_SYMBOL(node_2_cpu_mask);
 /* which node each logical CPU is on */
 int cpu_2_node[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 };
 EXPORT_SYMBOL(cpu_2_node);
@@ -647,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 8fdb1fb17a5f0ca457cdf0bdaa8e3d998fcd0ccf..4048397f1740bdbdce7d613e244ad3e9b3094dc0 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/utsname.h>
 
 #include <asm/uaccess.h>
+#include <asm/unistd.h>
 #include <asm/ipc.h>
 
 /*
@@ -210,7 +211,7 @@ asmlinkage int sys_uname(struct old_utsname __user * name)
        if (!name)
                return -EFAULT;
        down_read(&uts_sem);
-       err=copy_to_user(name, &system_utsname, sizeof (*name));
+       err = copy_to_user(name, utsname(), sizeof (*name));
        up_read(&uts_sem);
        return err?-EFAULT:0;
 }
@@ -226,16 +227,21 @@ asmlinkage int sys_olduname(struct oldold_utsname __user * name)
   
        down_read(&uts_sem);
        
-       error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
-       error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
-       error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
-       error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
-       error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
-       error |= __put_user(0,name->release+__OLD_UTS_LEN);
-       error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
-       error |= __put_user(0,name->version+__OLD_UTS_LEN);
-       error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
-       error |= __put_user(0,name->machine+__OLD_UTS_LEN);
+       error = __copy_to_user(&name->sysname, &utsname()->sysname,
+                              __OLD_UTS_LEN);
+       error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
+       error |= __copy_to_user(&name->nodename, &utsname()->nodename,
+                               __OLD_UTS_LEN);
+       error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
+       error |= __copy_to_user(&name->release, &utsname()->release,
+                               __OLD_UTS_LEN);
+       error |= __put_user(0, name->release + __OLD_UTS_LEN);
+       error |= __copy_to_user(&name->version, &utsname()->version,
+                               __OLD_UTS_LEN);
+       error |= __put_user(0, name->version + __OLD_UTS_LEN);
+       error |= __copy_to_user(&name->machine, &utsname()->machine,
+                               __OLD_UTS_LEN);
+       error |= __put_user(0, name->machine + __OLD_UTS_LEN);
        
        up_read(&uts_sem);
        
@@ -243,3 +249,17 @@ asmlinkage int sys_olduname(struct oldold_utsname __user * name)
 
        return error;
 }
+
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+       long __res;
+       asm volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx"
+       : "=a" (__res)
+       : "0" (__NR_execve),"ri" (filename),"c" (argv), "d" (envp) : "memory");
+       return __res;
+}
index 6820b8d643c7779a07328a1668fc41e4e8035542..00489b706d2719c2083172342569381b60f5ce7e 100644 (file)
@@ -357,9 +357,9 @@ void show_registers(struct pt_regs *regs)
                KERN_EMERG "EIP:    %04x:[<%08lx>]    %s VLI\n"
                KERN_EMERG "EFLAGS: %08lx   (%s %.*s)\n",
                smp_processor_id(), 0xffff & regs->xcs, regs->eip,
-               print_tainted(), regs->eflags, system_utsname.release,
-               (int)strcspn(system_utsname.version, " "),
-               system_utsname.version);
+               print_tainted(), regs->eflags, init_utsname()->release,
+               (int)strcspn(init_utsname()->version, " "),
+               init_utsname()->version);
        print_symbol(KERN_EMERG "EIP is at %s\n", regs->eip);
        printk(KERN_EMERG "eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
                regs->eax, regs->ebx, regs->ecx, regs->edx);
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 0b7f701d5cf7e38253465e82c1261c92dc854a15..70f7eb9fed3562aaa9e072376fb3efd759d7b28e 100644 (file)
@@ -516,7 +516,7 @@ source "arch/ia64/oprofile/Kconfig"
 
 config KPROBES
        bool "Kprobes (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && MODULES
+       depends on KALLSYMS && EXPERIMENTAL && MODULES
        help
          Kprobes allows you to trap at almost any kernel address and
          execute a callback function.  register_kprobe() establishes
index 0daacc20ed36e26c8600176b5332a5ce4a65b10f..246eb3d3757adc85db23f8892ed49beb5c0d5a11 100644 (file)
@@ -940,7 +940,7 @@ static inline void show_serial_version(void)
        printk(KERN_INFO " no serial options enabled\n");
 }
 
-static struct tty_operations hp_ops = {
+static const struct tty_operations hp_ops = {
        .open = rs_open,
        .close = rs_close,
        .write = rs_write,
index bddbd22706ed1ad76a791635b621784a80cde5a9..9d6a3f210148f3e1b9a775b8615a88841803e479 100644 (file)
@@ -125,6 +125,7 @@ sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __use
 
 int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
 {
+       compat_ino_t ino;
        int err;
 
        if ((u64) stat->size > MAX_NON_LFS ||
@@ -132,11 +133,15 @@ int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
            !old_valid_dev(stat->rdev))
                return -EOVERFLOW;
 
+       ino = stat->ino;
+       if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
+               return -EOVERFLOW;
+
        if (clear_user(ubuf, sizeof(*ubuf)))
                return -EFAULT;
 
        err  = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev);
-       err |= __put_user(stat->ino, &ubuf->st_ino);
+       err |= __put_user(ino, &ubuf->st_ino);
        err |= __put_user(stat->mode, &ubuf->st_mode);
        err |= __put_user(stat->nlink, &ubuf->st_nlink);
        err |= __put_user(high2lowuid(stat->uid), &ubuf->st_uid);
@@ -1222,16 +1227,20 @@ struct readdir32_callback {
 };
 
 static int
-filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
+filldir32 (void *__buf, const char *name, int namlen, loff_t offset, u64 ino,
           unsigned int d_type)
 {
        struct compat_dirent __user * dirent;
        struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
        int reclen = ROUND_UP(offsetof(struct compat_dirent, d_name) + namlen + 1, 4);
+       u32 d_ino;
 
        buf->error = -EINVAL;   /* only used if we fail.. */
        if (reclen > buf->count)
                return -EINVAL;
+       d_ino = ino;
+       if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+               return -EOVERFLOW;
        buf->error = -EFAULT;   /* only used if we fail.. */
        dirent = buf->previous;
        if (dirent)
@@ -1239,7 +1248,7 @@ filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
                        return -EFAULT;
        dirent = buf->current_dir;
        buf->previous = dirent;
-       if (put_user(ino, &dirent->d_ino)
+       if (put_user(d_ino, &dirent->d_ino)
            || put_user(reclen, &dirent->d_reclen)
            || copy_to_user(dirent->d_name, name, namlen)
            || put_user(0, dirent->d_name + namlen))
@@ -1287,17 +1296,21 @@ out:
 }
 
 static int
-fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino,
+fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, u64 ino,
              unsigned int d_type)
 {
        struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
        struct old_linux32_dirent __user * dirent;
+       u32 d_ino;
 
        if (buf->count)
                return -EINVAL;
+       d_ino = ino;
+       if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+               return -EOVERFLOW;
        buf->count++;
        dirent = buf->dirent;
-       if (put_user(ino, &dirent->d_ino)
+       if (put_user(d_ino, &dirent->d_ino)
            || put_user(offset, &dirent->d_offset)
            || put_user(namlen, &dirent->d_namlen)
            || copy_to_user(dirent->d_name, name, namlen)
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 12701cf32d9944de96a3fa609788d50fc79b8518..3390b7c5a63fab53035d6fa2986798347237f047 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * ia64/kernel/entry.S
+ * arch/ia64/kernel/entry.S
  *
  * Kernel entry points.
  *
@@ -492,11 +492,11 @@ GLOBAL_ENTRY(prefetch_stack)
        br.ret.sptk.many rp
 END(prefetch_stack)
 
-GLOBAL_ENTRY(execve)
+GLOBAL_ENTRY(kernel_execve)
        mov r15=__NR_execve                     // put syscall number in place
        break __BREAK_SYSCALL
        br.ret.sptk.many rp
-END(execve)
+END(kernel_execve)
 
 GLOBAL_ENTRY(clone)
        mov r15=__NR_clone                      // put syscall number in place
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
index 169ec3a7156ce4dc349769e90ead997bed4f4329..51217d63285ea35122d9373647e2dd40c5cd0346 100644 (file)
@@ -90,7 +90,7 @@ static void __kprobes update_kprobe_inst_flag(uint template, uint  slot,
        p->ainsn.target_br_reg = 0;
 
        /* Check for Break instruction
-        * Bits 37:40 Major opcode to be zero
+        * Bits 37:40 Major opcode to be zero
         * Bits 27:32 X6 to be zero
         * Bits 32:35 X3 to be zero
         */
@@ -104,19 +104,19 @@ static void __kprobes update_kprobe_inst_flag(uint template, uint  slot,
                switch (major_opcode) {
                  case INDIRECT_CALL_OPCODE:
                        p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
-                       p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
-                       break;
+                       p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
+                       break;
                  case IP_RELATIVE_PREDICT_OPCODE:
                  case IP_RELATIVE_BRANCH_OPCODE:
                        p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR;
-                       break;
+                       break;
                  case IP_RELATIVE_CALL_OPCODE:
-                       p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR;
-                       p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
-                       p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
-                       break;
+                       p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR;
+                       p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
+                       p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
+                       break;
                }
-       } else if (bundle_encoding[template][slot] == X) {
+       } else if (bundle_encoding[template][slot] == X) {
                switch (major_opcode) {
                  case LONG_CALL_OPCODE:
                        p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
@@ -258,18 +258,18 @@ static void __kprobes get_kprobe_inst(bundle_t *bundle, uint slot,
 
        switch (slot) {
          case 0:
-               *major_opcode = (bundle->quad0.slot0 >> SLOT0_OPCODE_SHIFT);
-               *kprobe_inst = bundle->quad0.slot0;
-               break;
+               *major_opcode = (bundle->quad0.slot0 >> SLOT0_OPCODE_SHIFT);
+               *kprobe_inst = bundle->quad0.slot0;
+                 break;
          case 1:
-               *major_opcode = (bundle->quad1.slot1_p1 >> SLOT1_p1_OPCODE_SHIFT);
-               kprobe_inst_p0 = bundle->quad0.slot1_p0;
-               kprobe_inst_p1 = bundle->quad1.slot1_p1;
-               *kprobe_inst = kprobe_inst_p0 | (kprobe_inst_p1 << (64-46));
+               *major_opcode = (bundle->quad1.slot1_p1 >> SLOT1_p1_OPCODE_SHIFT);
+               kprobe_inst_p0 = bundle->quad0.slot1_p0;
+               kprobe_inst_p1 = bundle->quad1.slot1_p1;
+               *kprobe_inst = kprobe_inst_p0 | (kprobe_inst_p1 << (64-46));
                break;
          case 2:
-               *major_opcode = (bundle->quad1.slot2 >> SLOT2_OPCODE_SHIFT);
-               *kprobe_inst = bundle->quad1.slot2;
+               *major_opcode = (bundle->quad1.slot2 >> SLOT2_OPCODE_SHIFT);
+               *kprobe_inst = bundle->quad1.slot2;
                break;
        }
 }
@@ -290,11 +290,11 @@ static int __kprobes valid_kprobe_addr(int template, int slot,
                return -EINVAL;
        }
 
-       if (in_ivt_functions(addr)) {
-               printk(KERN_WARNING "Kprobes can't be inserted inside "
+       if (in_ivt_functions(addr)) {
+               printk(KERN_WARNING "Kprobes can't be inserted inside "
                                "IVT functions at 0x%lx\n", addr);
-               return -EINVAL;
-       }
+               return -EINVAL;
+       }
 
        if (slot == 1 && bundle_encoding[template][1] != L) {
                printk(KERN_WARNING "Inserting kprobes on slot #1 "
@@ -338,12 +338,13 @@ static void kretprobe_trampoline(void)
 int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
 {
        struct kretprobe_instance *ri = NULL;
-       struct hlist_head *head;
+       struct hlist_head *head, empty_rp;
        struct hlist_node *node, *tmp;
        unsigned long flags, orig_ret_address = 0;
        unsigned long trampoline_address =
                ((struct fnptr *)kretprobe_trampoline)->ip;
 
+       INIT_HLIST_HEAD(&empty_rp);
        spin_lock_irqsave(&kretprobe_lock, flags);
        head = kretprobe_inst_table_head(current);
 
@@ -369,7 +370,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
                        ri->rp->handler(ri, regs);
 
                orig_ret_address = (unsigned long)ri->ret_addr;
-               recycle_rp_inst(ri);
+               recycle_rp_inst(ri, &empty_rp);
 
                if (orig_ret_address != trampoline_address)
                        /*
@@ -387,6 +388,10 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
        spin_unlock_irqrestore(&kretprobe_lock, flags);
        preempt_enable_no_resched();
 
+       hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
+               hlist_del(&ri->hlist);
+               kfree(ri);
+       }
        /*
         * By returning a non-zero value, we are telling
         * kprobe_handler() that we don't want the post_handler
@@ -424,14 +429,14 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
        bundle_t *bundle;
 
        bundle = &((kprobe_opcode_t *)kprobe_addr)->bundle;
-       template = bundle->quad0.template;
+       template = bundle->quad0.template;
 
        if(valid_kprobe_addr(template, slot, addr))
                return -EINVAL;
 
        /* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */
-       if (slot == 1 && bundle_encoding[template][1] == L)
-               slot++;
+       if (slot == 1 && bundle_encoding[template][1] == L)
+               slot++;
 
        /* Get kprobe_inst and major_opcode from the bundle */
        get_kprobe_inst(bundle, slot, &kprobe_inst, &major_opcode);
@@ -489,21 +494,22 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)
  */
 static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
 {
-       unsigned long bundle_addr = (unsigned long) (&p->ainsn.insn->bundle);
-       unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL;
-       unsigned long template;
-       int slot = ((unsigned long)p->addr & 0xf);
+       unsigned long bundle_addr = (unsigned long) (&p->ainsn.insn->bundle);
+       unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL;
+       unsigned long template;
+       int slot = ((unsigned long)p->addr & 0xf);
 
        template = p->ainsn.insn->bundle.quad0.template;
 
-       if (slot == 1 && bundle_encoding[template][1] == L)
-               slot = 2;
+       if (slot == 1 && bundle_encoding[template][1] == L)
+               slot = 2;
 
        if (p->ainsn.inst_flag) {
 
                if (p->ainsn.inst_flag & INST_FLAG_FIX_RELATIVE_IP_ADDR) {
                        /* Fix relative IP address */
-                       regs->cr_iip = (regs->cr_iip - bundle_addr) + resume_addr;
+                       regs->cr_iip = (regs->cr_iip - bundle_addr) +
+                                       resume_addr;
                }
 
                if (p->ainsn.inst_flag & INST_FLAG_FIX_BRANCH_REG) {
@@ -540,18 +546,18 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
        }
 
        if (slot == 2) {
-               if (regs->cr_iip == bundle_addr + 0x10) {
-                       regs->cr_iip = resume_addr + 0x10;
-               }
-       } else {
-               if (regs->cr_iip == bundle_addr) {
-                       regs->cr_iip = resume_addr;
-               }
+               if (regs->cr_iip == bundle_addr + 0x10) {
+                       regs->cr_iip = resume_addr + 0x10;
+               }
+       } else {
+               if (regs->cr_iip == bundle_addr) {
+                       regs->cr_iip = resume_addr;
+               }
        }
 
 turn_ss_off:
-       /* Turn off Single Step bit */
-       ia64_psr(regs)->ss = 0;
+       /* Turn off Single Step bit */
+       ia64_psr(regs)->ss = 0;
 }
 
 static void __kprobes prepare_ss(struct kprobe *p, struct pt_regs *regs)
@@ -587,7 +593,7 @@ static int __kprobes is_ia64_break_inst(struct pt_regs *regs)
 
        /* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */
        if (slot == 1 && bundle_encoding[template][1] == L)
-               slot++;
+               slot++;
 
        /* Get Kprobe probe instruction at given slot*/
        get_kprobe_inst(&bundle, slot, &kprobe_inst, &major_opcode);
@@ -627,7 +633,7 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
                if (p) {
                        if ((kcb->kprobe_status == KPROBE_HIT_SS) &&
                             (p->ainsn.inst_flag == INST_FLAG_BREAK_INST)) {
-                               ia64_psr(regs)->ss = 0;
+                               ia64_psr(regs)->ss = 0;
                                goto no_kprobe;
                        }
                        /* We have reentered the pre_kprobe_handler(), since
@@ -887,7 +893,7 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
         * fix the return address to our jprobe_inst_return() function
         * in the jprobes.S file
         */
-       regs->b0 = ((struct fnptr *)(jprobe_inst_return))->ip;
+       regs->b0 = ((struct fnptr *)(jprobe_inst_return))->ip;
 
        return 1;
 }
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 20340631179f669fd7d9216d85f210c2a4cf381e..a78b45f5fe2f9d3aef7c9c8aa8012987b0558a0e 100644 (file)
@@ -28,6 +28,7 @@ u16 cpu_to_node_map[NR_CPUS] __cacheline_aligned;
 EXPORT_SYMBOL(cpu_to_node_map);
 
 cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
+EXPORT_SYMBOL(node_to_cpu_mask);
 
 void __cpuinit map_cpu_to_node(int cpu, int nid)
 {
index ea914cc6812a0a327cd73802f4b0e2b6beacd42b..51922b98086afb1919a174772206263ab9519a39 100644 (file)
@@ -8,8 +8,6 @@
  * 2005-10-07 Keith Owens <kaos@sgi.com>
  *           Add notify_die() hooks.
  */
-#define __KERNEL_SYSCALLS__    /* see <asm/unistd.h> */
-
 #include <linux/cpu.h>
 #include <linux/pm.h>
 #include <linux/elf.h>
index 84f93c0f2c666b15d3f70c3df47c3c17a5949ad0..c4caa800349220d22b69dc25ac12e490d059c85d 100644 (file)
@@ -54,7 +54,6 @@
 #include <asm/processor.h>
 #include <asm/sal.h>
 #include <asm/sections.h>
-#include <asm/serial.h>
 #include <asm/setup.h>
 #include <asm/smp.h>
 #include <asm/system.h>
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 b632b9c1e3b3e1785ffdc6b678e495c59b805dba..462ea178f49abadfed37375141629013fda98e62 100644 (file)
@@ -423,7 +423,7 @@ static int sn_topology_show(struct seq_file *s, void *d)
                        "coherency_domain %d, "
                        "region_size %d\n",
 
-                       partid, system_utsname.nodename,
+                       partid, utsname()->nodename,
                        shubtype ? "shub2" : "shub1", 
                        (u64)nasid_mask << nasid_shift, nasid_msb, nasid_shift,
                        system_size, sharing_size, coher, region_size);
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 a9cea32eb8246286924667bbef46291547297696..b567351f3c5236d41e0b108a2ba516a86fc170fd 100644 (file)
@@ -25,6 +25,8 @@
 #include <asm/cachectl.h>
 #include <asm/cacheflush.h>
 #include <asm/ipc.h>
+#include <asm/syscall.h>
+#include <asm/unistd.h>
 
 /*
  * sys_tas() - test-and-set
@@ -205,7 +207,7 @@ asmlinkage int sys_uname(struct old_utsname * name)
        if (!name)
                return -EFAULT;
        down_read(&uts_sem);
-       err=copy_to_user(name, &system_utsname, sizeof (*name));
+       err = copy_to_user(name, utsname(), sizeof (*name));
        up_read(&uts_sem);
        return err?-EFAULT:0;
 }
@@ -223,3 +225,21 @@ asmlinkage int sys_cachectl(char *addr, int nbytes, int op)
        return -ENOSYS;
 }
 
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+       register long __scno __asm__ ("r7") = __NR_execve;
+       register long __arg3 __asm__ ("r2") = (long)(envp);
+       register long __arg2 __asm__ ("r1") = (long)(argv);
+       register long __res __asm__ ("r0") = (long)(filename);
+       __asm__ __volatile__ (
+               "trap #" SYSCALL_VECTOR "|| nop"
+               : "=r" (__res)
+               : "r" (__scno), "0" (__res), "r" (__arg2),
+                       "r" (__arg3)
+               : "memory");
+       return __res;
+}
index 143c552d38f36a6ca799bee01e8a2e418934cdb8..90238a8c9e14996cf48daca92b083390c703e6a4 100644 (file)
@@ -27,6 +27,7 @@
 #include <asm/traps.h>
 #include <asm/ipc.h>
 #include <asm/page.h>
+#include <asm/unistd.h>
 
 /*
  * sys_pipe() is the normal C calling standard for creating
@@ -663,3 +664,18 @@ asmlinkage int sys_getpagesize(void)
 {
        return PAGE_SIZE;
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+       register long __res asm ("%d0") = __NR_execve;
+       register long __a asm ("%d1") = (long)(filename);
+       register long __b asm ("%d2") = (long)(argv);
+       register long __c asm ("%d3") = (long)(envp);
+       asm volatile ("trap  #0" : "+d" (__res)
+                       : "d" (__a), "d" (__b), "d" (__c));
+       return __res;
+}
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 d87e1e0a1336d8aed5f6dffeeb61e75616d03870..c3494b8447d155f890a319097b97fdf352eb4319 100644 (file)
@@ -26,6 +26,7 @@
 #include <asm/traps.h>
 #include <asm/ipc.h>
 #include <asm/cacheflush.h>
+#include <asm/unistd.h>
 
 /*
  * sys_pipe() is the normal C calling standard for creating
@@ -206,3 +207,17 @@ asmlinkage int sys_getpagesize(void)
        return PAGE_SIZE;
 }
 
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+       register long __res asm ("%d0") = __NR_execve;
+       register long __a asm ("%d1") = (long)(filename);
+       register long __b asm ("%d2") = (long)(argv);
+       register long __c asm ("%d3") = (long)(envp);
+       asm volatile ("trap  #0" : "+d" (__res)
+                       : "d" (__a), "d" (__b), "d" (__c));
+       return __res;
+}
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 30750c54bdf5169564855012899f6e2acb42299d..bfab055ad7cc3d98e358b21c60e6200bb10c557a 100644 (file)
@@ -203,39 +203,6 @@ config MIPS_EV64120
          <http://www.marvell.com/>.  Say Y here if you wish to build a
          kernel for this platform.
 
-config MIPS_IVR
-       bool "Globespan IVR board"
-       select DMA_NONCOHERENT
-       select HW_HAS_PCI
-       select ITE_BOARD_GEN
-       select SYS_HAS_CPU_NEVADA
-       select SYS_SUPPORTS_32BIT_KERNEL
-       select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
-       select SYS_SUPPORTS_LITTLE_ENDIAN
-       help
-         This is an evaluation board built by Globespan to showcase thir
-         iVR (Internet Video Recorder) design. It utilizes a QED RM5231
-         R5000 MIPS core. More information can be found out their website
-         located at <http://www.globespan.net/>. Say Y here if you wish to
-         build a kernel for this platform.
-
-config MIPS_ITE8172
-       bool "ITE 8172G board"
-       select DMA_NONCOHERENT
-       select HW_HAS_PCI
-       select ITE_BOARD_GEN
-       select SYS_HAS_CPU_R5432
-       select SYS_HAS_CPU_NEVADA
-       select SYS_SUPPORTS_32BIT_KERNEL
-       select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
-       select SYS_SUPPORTS_LITTLE_ENDIAN
-       help
-         Ths is an evaluation board made by ITE <http://www.ite.com.tw/>
-         with ATX form factor that utilizes a MIPS R5000 to work with its
-         ITE8172G companion internet appliance chip. The MIPS core can be
-         either a NEC Vr5432 or QED RM5231. Say Y here if you wish to build
-         a kernel for this platform.
-
 config MACH_JAZZ
        bool "Jazz family of machines"
        select ARC
@@ -537,6 +504,7 @@ config QEMU
        select SYS_HAS_CPU_MIPS32_R1
        select SYS_SUPPORTS_32BIT_KERNEL
        select SYS_SUPPORTS_BIG_ENDIAN
+       select SYS_SUPPORTS_LITTLE_ENDIAN
        select ARCH_SPARSEMEM_ENABLE
        help
          Qemu is a software emulator which among other architectures also
@@ -803,7 +771,6 @@ endchoice
 source "arch/mips/ddb5xxx/Kconfig"
 source "arch/mips/gt64120/ev64120/Kconfig"
 source "arch/mips/jazz/Kconfig"
-source "arch/mips/ite-boards/Kconfig"
 source "arch/mips/lasat/Kconfig"
 source "arch/mips/momentum/Kconfig"
 source "arch/mips/pmc-sierra/Kconfig"
@@ -836,6 +803,10 @@ config GENERIC_CALIBRATE_DELAY
        bool
        default y
 
+config GENERIC_TIME
+       bool
+       default y
+
 config SCHED_NO_NO_OMIT_FRAME_POINTER
        bool
        default y
@@ -963,9 +934,6 @@ config MIPS_RM9122
 config PCI_MARVELL
        bool
 
-config ITE_BOARD_GEN
-       bool
-
 config SOC_AU1000
        bool
        select SOC_AU1X00
@@ -1049,16 +1017,6 @@ config AU1X00_USB_DEVICE
        depends on MIPS_PB1500 || MIPS_PB1100 || MIPS_PB1000
        default n
 
-config IT8172_CIR
-       bool
-       depends on MIPS_ITE8172 || MIPS_IVR
-       default y
-
-config IT8712
-       bool
-       depends on MIPS_ITE8172
-       default y
-
 config BOOT_ELF32
        bool
 
@@ -1841,6 +1799,14 @@ config RWSEM_GENERIC_SPINLOCK
        bool
        default y
 
+config LOCKDEP_SUPPORT
+       bool
+       default y
+
+config STACKTRACE_SUPPORT
+       bool
+       default y
+
 source "init/Kconfig"
 
 menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)"
index e521826b423459bc5e3c9ff018954420f346403c..2124350ab94dfa88e609e7fe193f09d45c6c5bf7 100644 (file)
@@ -286,19 +286,6 @@ core-$(CONFIG_WR_PPMC)             += arch/mips/gt64120/wrppmc/
 cflags-$(CONFIG_WR_PPMC)               += -Iinclude/asm-mips/mach-wrppmc
 load-$(CONFIG_WR_PPMC)         += 0xffffffff80100000
 
-#
-# Globespan IVR eval board with QED 5231 CPU
-#
-core-$(CONFIG_ITE_BOARD_GEN)   += arch/mips/ite-boards/generic/
-core-$(CONFIG_MIPS_IVR)                += arch/mips/ite-boards/ivr/
-load-$(CONFIG_MIPS_IVR)                += 0xffffffff80100000
-
-#
-# ITE 8172 eval board with QED 5231 CPU
-#
-core-$(CONFIG_MIPS_ITE8172)    += arch/mips/ite-boards/qed-4n-s01b/
-load-$(CONFIG_MIPS_ITE8172)    += 0xffffffff80100000
-
 #
 # For all MIPS, Inc. eval boards
 #
diff --git a/arch/mips/basler/excite/excite_flashtest.c b/arch/mips/basler/excite/excite_flashtest.c
deleted file mode 100644 (file)
index f0024a8..0000000
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
-*  Copyright (C) 2005 by Basler Vision Technologies AG
-*  Author: Thies Moeller <thies.moeller@baslerweb.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/module.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/kernel.h>
-
-#include <excite.h>
-
-#include <asm/io.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-#include <asm/rm9k-ocd.h> // for ocd_write
-#include <linux/workqueue.h> // for queue
-
-#include "excite_nandflash.h"
-#include "nandflash.h"
-
-#define PFX "excite flashtest: "
-typedef void __iomem *io_reg_t;
-
-#define io_readb(__a__)                __raw_readb((__a__))
-#define io_writeb(__v__, __a__)        __raw_writeb((__v__), (__a__))
-
-
-
-static inline const struct resource *excite_nandflash_get_resource(
-       struct platform_device *d, unsigned long flags, const char *basename)
-{
-       const char fmt[] = "%s_%u";
-       char buf[80];
-
-       if (unlikely(snprintf(buf, sizeof buf, fmt, basename, d->id) >= sizeof buf))
-               return NULL;
-
-       return platform_get_resource_byname(d, flags, buf);
-}
-
-static inline io_reg_t
-excite_nandflash_map_regs(struct platform_device *d, const char *basename)
-{
-       void *result = NULL;
-       const struct resource *const r =
-           excite_nandflash_get_resource(d, IORESOURCE_MEM, basename);
-       if (r)
-          result = ioremap_nocache(r->start, r->end + 1 - r->start);
-       return result;
-}
-
-/* controller and mtd information */
-
-struct excite_nandflash_drvdata {
-       struct mtd_info board_mtd;
-       struct nand_chip board_chip;
-       io_reg_t regs;
-};
-
-
-/* command and control functions */
-static void excite_nandflash_hwcontrol(struct mtd_info *mtd, int cmd)
-{
-       struct nand_chip *this = mtd->priv;
-       io_reg_t regs = container_of(mtd,struct excite_nandflash_drvdata,board_mtd)->regs;
-
-       switch (cmd) {
-       /* Select the command latch */
-       case NAND_CTL_SETCLE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_CMD;
-               break;
-       /* Deselect the command latch */
-       case NAND_CTL_CLRCLE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_DATA;
-               break;
-       /* Select the address latch */
-       case NAND_CTL_SETALE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_ADDR;
-               break;
-       /* Deselect the address latch */
-       case NAND_CTL_CLRALE: this->IO_ADDR_W = regs  + EXCITE_NANDFLASH_DATA;
-               break;
-       /* Select the chip  -- not used */
-       case NAND_CTL_SETNCE:
-               break;
-       /* Deselect the chip -- not used */
-       case NAND_CTL_CLRNCE:
-               break;
-       }
-
-       this->IO_ADDR_R = this->IO_ADDR_W;
-}
-
-/* excite_nandflash_devready()
- *
- * returns 0 if the nand is busy, 1 if it is ready
- */
-static int excite_nandflash_devready(struct mtd_info *mtd)
-{
-       struct excite_nandflash_drvdata *drvdata =
-           container_of(mtd, struct excite_nandflash_drvdata, board_mtd);
-
-       return io_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS);
-}
-
-/* device management functions */
-
-/* excite_nandflash_remove
- *
- * called by device layer to remove the driver
- * the binding to the mtd and all allocated
- * resources are released
- */
-static int excite_nandflash_remove(struct device *dev)
-{
-       struct excite_nandflash_drvdata *this = dev_get_drvdata(dev);
-
-       pr_info(PFX "remove");
-
-       dev_set_drvdata(dev, NULL);
-
-       if (this == NULL) {
-               pr_debug(PFX "call remove without private data!!");
-               return 0;
-       }
-
-
-       /* free the common resources */
-       if (this->regs != NULL) {
-               iounmap(this->regs);
-               this->regs = NULL;
-       }
-
-       kfree(this);
-
-       return 0;
-}
-
-static int elapsed;
-
-void my_workqueue_handler(void *arg)
-{
-       elapsed = 1;
-}
-
-DECLARE_WORK(sigElapsed, my_workqueue_handler, 0);
-
-
-/* excite_nandflash_probe
- *
- * called by device layer when it finds a device matching
- * one our driver can handled. This code checks to see if
- * it can allocate all necessary resources then calls the
- * nand layer to look for devices
-*/
-static int excite_nandflash_probe(struct device *dev)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-
-       struct excite_nandflash_drvdata *drvdata;           /* private driver data     */
-       struct nand_chip              *board_chip;  /* private flash chip data */
-       struct mtd_info               *board_mtd;   /* mtd info for this board */
-
-       int err      = 0;
-       int count    = 0;
-       struct timeval tv,endtv;
-       unsigned int dt;
-
-       pr_info(PFX "probe dev: (%p)\n", dev);
-
-       pr_info(PFX "adjust LB timing\n");
-       ocd_writel(0x00000330, LDP2);
-
-       drvdata = kmalloc(sizeof(*drvdata), GFP_KERNEL);
-       if (unlikely(!drvdata)) {
-               printk(KERN_ERR PFX "no memory for drvdata\n");
-               err = -ENOMEM;
-               goto mem_error;
-       }
-
-       /* Initialize structures */
-       memset(drvdata, 0, sizeof(*drvdata));
-
-       /* bind private data into driver */
-       dev_set_drvdata(dev, drvdata);
-
-       /* allocate and map the resource */
-       drvdata->regs =
-           excite_nandflash_map_regs(pdev, EXCITE_NANDFLASH_RESOURCE_REGS);
-
-       if (unlikely(!drvdata->regs)) {
-               printk(KERN_ERR PFX "cannot reserve register region\n");
-               err = -ENXIO;
-               goto io_error;
-       }
-
-       /* initialise our chip */
-       board_chip = &drvdata->board_chip;
-
-       board_chip->IO_ADDR_R = drvdata->regs + EXCITE_NANDFLASH_DATA;
-       board_chip->IO_ADDR_W = drvdata->regs + EXCITE_NANDFLASH_DATA;
-
-       board_chip->hwcontrol = excite_nandflash_hwcontrol;
-       board_chip->dev_ready = excite_nandflash_devready;
-
-       board_chip->chip_delay = 25;
-       #if 0
-       /* TODO: speedup the initial scan */
-       board_chip->options = NAND_USE_FLASH_BBT;
-       #endif
-       board_chip->eccmode = NAND_ECC_SOFT;
-
-       /* link chip to mtd */
-       board_mtd = &drvdata->board_mtd;
-       board_mtd->priv = board_chip;
-
-
-       pr_info(PFX "FlashTest\n");
-       elapsed = 0;
-/*     schedule_delayed_work(&sigElapsed, 1*HZ);
-       while (!elapsed) {
-               io_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS);
-               count++;
-       }
-       pr_info(PFX "reads in 1 sec --> %d\n",count);
-*/
-       do_gettimeofday(&tv);
-       for (count = 0 ; count < 1000000; count ++) {
-               io_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS);
-       }
-       do_gettimeofday(&endtv);
-       dt = (endtv.tv_sec - tv.tv_sec) * 1000000 + endtv.tv_usec  - tv.tv_usec;
-       pr_info(PFX "%8d us timeval\n",dt);
-       pr_info(PFX "EndFlashTest\n");
-
-/*      return with error to unload everything
-*/
-io_error:
-       iounmap(drvdata->regs);
-
-mem_error:
-       kfree(drvdata);
-
-       if (err == 0)
-               err = -EINVAL;
-       return err;
-}
-
-static struct device_driver excite_nandflash_driver = {
-       .name = "excite_nand",
-       .bus = &platform_bus_type,
-       .probe = excite_nandflash_probe,
-       .remove = excite_nandflash_remove,
-};
-
-static int __init excite_nandflash_init(void)
-{
-       pr_info(PFX "register Driver (Rev: $Revision:$)\n");
-       return driver_register(&excite_nandflash_driver);
-}
-
-static void __exit excite_nandflash_exit(void)
-{
-       driver_unregister(&excite_nandflash_driver);
-       pr_info(PFX "Driver unregistered");
-}
-
-module_init(excite_nandflash_init);
-module_exit(excite_nandflash_exit);
-
-MODULE_AUTHOR("Thies Moeller <thies.moeller@baslerweb.com>");
-MODULE_DESCRIPTION("Basler eXcite NAND-Flash driver");
-MODULE_LICENSE("GPL");
index c01a0170e5903e51851d9743566ea3645988bf7f..0b347cffc768d5c39b26f51e0ebf60f8b35729d8 100644 (file)
@@ -23,7 +23,6 @@
 #include <asm/processor.h>
 #include <asm/reboot.h>
 #include <asm/gt64120.h>
-#include <asm/serial.h>
 
 #include <asm/mach-cobalt/cobalt.h>
 
index d3705284de39bf45d5c09dd34a1b7c7140168113..35931bedc3df2449452d3e74222065120f56d704 100644 (file)
@@ -161,6 +161,8 @@ CONFIG_HZ=100
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1304,6 +1306,7 @@ CONFIG_NLS_UTF8=m
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index e12a475dcbf43cf85ef65bc5842837cda761ab2c..c6a015940b410d2929d1af85d6278f413bed8486 100644 (file)
@@ -167,6 +167,8 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_PREEMPT_BKL is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -904,6 +906,7 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_PRINTK_TIME=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
index bfade9abb767f7bf1c987806959f3240831113c1..e5358121d2da0ff928e2e89ca3487f91f3d2d36c 100644 (file)
@@ -149,6 +149,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -891,6 +893,7 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index 4baf2ff1128a0ba8b24c3d854b113969402dceb0..adf1e8c98c654de024b5acfd580b1e1a45e7dc1d 100644 (file)
@@ -146,6 +146,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -889,6 +891,7 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index 93cca1585bc342c08fb2ea2913c1698205379deb..4fd29ffdfb8dafd22e9fbf43ded53215e7807124 100644 (file)
@@ -147,6 +147,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1006,6 +1008,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index ffd99252a8376c9b83bd1cbc1797bf750ca5aa41..025b960ba990fb0e95cb78a1680f1aca76edbebf 100644 (file)
@@ -147,6 +147,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1006,6 +1008,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index 63eac5e89b9cdd63ae4208f8a261d4264a0d342d..80c9dd98f897fc1e088c176517861fb6aed9619a 100644 (file)
@@ -147,6 +147,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1087,6 +1089,7 @@ CONFIG_NLS_UTF8=m
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index 25a095f7dc4ef56dcab70debf6a207ce333c1111..6caa90b0e1766fd3991fc1c1ea285147746574f1 100644 (file)
@@ -149,6 +149,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1290,6 +1292,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index dda469c842b35dedff228dd521e1229d5daa2f0e..c6cae86c6ab7c5f73a08d493807b644e9d5b4cc0 100644 (file)
@@ -148,6 +148,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1111,6 +1113,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index fcd3dd19bc744e252440c318cdcc58edabfd9c3d..72f24001c99e88a24061d7b47303d4a84ed66269 100644 (file)
@@ -146,6 +146,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -852,6 +854,7 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index 8683e0df12e07615aaff8425a1490aa070fa5c41..fe1387eb83c9850cd49d94c98a4888d0f662b6df 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:01 2006
+# Linux kernel version: 2.6.18
+# Tue Oct  3 11:57:53 2006
 #
 CONFIG_MIPS=y
 
@@ -147,6 +147,8 @@ CONFIG_HZ=128
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -165,27 +167,28 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
-CONFIG_RELAY=y
+# CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 # CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -203,6 +206,7 @@ CONFIG_KMOD=y
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -229,7 +233,6 @@ CONFIG_MMU=y
 #
 # PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCCARD is not set
 
 #
 # PCI Hotplug Support
@@ -256,9 +259,10 @@ CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
-# CONFIG_NET_KEY is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_NET_KEY=m
 CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_FIB_HASH=y
 CONFIG_IP_PNP=y
@@ -267,22 +271,37 @@ CONFIG_IP_PNP_BOOTP=y
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
 # CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-# CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=y
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+# CONFIG_IPV6_TUNNEL is not set
+CONFIG_IPV6_SUBTREES=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
 CONFIG_NETWORK_SECMARK=y
 # CONFIG_NETFILTER is not set
 
@@ -302,14 +321,13 @@ CONFIG_NETWORK_SECMARK=y
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
+CONFIG_VLAN_8021Q=m
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -325,13 +343,8 @@ CONFIG_NETWORK_SECMARK=y
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-CONFIG_IEEE80211=m
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=m
-CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_SOFTMAC=m
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
-CONFIG_WIRELESS_EXT=y
+# CONFIG_IEEE80211 is not set
+CONFIG_FIB_RULES=y
 
 #
 # Device Drivers
@@ -342,8 +355,6 @@ CONFIG_WIRELESS_EXT=y
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-# CONFIG_DEBUG_DRIVER is not set
 # CONFIG_SYS_HYPERVISOR is not set
 
 #
@@ -385,8 +396,9 @@ CONFIG_BLK_DEV_LOOP=m
 #
 # SCSI device support
 #
-CONFIG_RAID_ATTRS=m
+# CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -408,12 +420,13 @@ CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_LOGGING is not set
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=m
 # CONFIG_SCSI_FC_ATTRS is not set
 CONFIG_SCSI_ISCSI_ATTRS=m
 CONFIG_SCSI_SAS_ATTRS=m
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
@@ -421,9 +434,13 @@ CONFIG_SCSI_SAS_ATTRS=m
 CONFIG_ISCSI_TCP=m
 CONFIG_SCSI_DECNCR=y
 # CONFIG_SCSI_DECSII is not set
-# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_DEBUG is not set
 
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
 #
 # Multi-device support (RAID and LVM)
 #
@@ -454,18 +471,7 @@ CONFIG_NETDEVICES=y
 #
 # PHY device support
 #
-CONFIG_PHYLIB=m
-
-#
-# MII PHY device drivers
-#
-CONFIG_MARVELL_PHY=m
-CONFIG_DAVICOM_PHY=m
-CONFIG_QSEMI_PHY=m
-CONFIG_LXT_PHY=m
-CONFIG_CICADA_PHY=m
-CONFIG_VITESSE_PHY=m
-CONFIG_SMSC_PHY=m
+# CONFIG_PHYLIB is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -710,7 +716,12 @@ CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
 CONFIG_EXT2_FS_SECURITY=y
 # CONFIG_EXT2_FS_XIP is not set
-# CONFIG_EXT3_FS is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
@@ -745,11 +756,13 @@ CONFIG_FUSE_FS=m
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=y
 
 #
 # Miscellaneous filesystems
@@ -767,7 +780,7 @@ CONFIG_RAMFS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_SYSV_FS is not set
 CONFIG_UFS_FS=y
-# CONFIG_UFS_FS_WRITE is not set
+CONFIG_UFS_FS_WRITE=y
 # CONFIG_UFS_DEBUG is not set
 
 #
@@ -775,24 +788,25 @@ CONFIG_UFS_FS=y
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V3_ACL=y
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
 # CONFIG_9P_FS is not set
+CONFIG_GENERIC_ACL=y
 
 #
 # Partition Types
@@ -828,45 +842,31 @@ CONFIG_ULTRIX_PARTITION=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
-CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_RT_MUTEXES is not set
-# CONFIG_RT_MUTEX_TESTER is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_RWSEMS is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-# CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_FS is not set
-# CONFIG_DEBUG_VM is not set
-CONFIG_FORCED_INLINING=y
-# CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
-# CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_KGDB is not set
-# CONFIG_RUNTIME_DEBUG is not set
-# CONFIG_MIPS_UNCACHED is not set
 
 #
 # Security options
 #
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 
 #
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=m
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
@@ -876,9 +876,12 @@ CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
 CONFIG_CRYPTO_DES=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -900,7 +903,7 @@ CONFIG_CRYPTO_CRC32C=m
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
-CONFIG_CRC16=m
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
index 4ace61c95778992ad929c2d11a45b9b206655569..6133c28beb8c757db6f17b52ef4c1e2dd38234f3 100644 (file)
@@ -147,6 +147,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
index 5847c916c130a90bf79b9e7f84f28be32ce809f7..a484b7d396fc8a9ab4c0830b21b2f47c3506b80f 100644 (file)
@@ -147,6 +147,8 @@ CONFIG_HZ=1000
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_PREEMPT_BKL=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1180,6 +1182,7 @@ CONFIG_NLS_UTF8=m
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index bc4c4f125c480087235a66bf41f2084b4ab11be2..21bfcdebf8f53664cc0207f778ad57f78b62ec26 100644 (file)
@@ -148,6 +148,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -842,6 +844,7 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index eb87cbbfd03729923e9753d635268b28595a8057..1a5b06cfb4d6b9d63685801055bb4247e222a017 100644 (file)
@@ -149,6 +149,8 @@ CONFIG_HZ=1000
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_PREEMPT_BKL=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1184,6 +1186,7 @@ CONFIG_NLS_ISO8859_1=m
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index cc9b24eda9e89480f17b0ddfb09d506d86febdae..21d53e0c9ee84c5126881129026a9224eddcdd20 100644 (file)
@@ -153,6 +153,8 @@ CONFIG_HZ=1000
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1147,6 +1149,7 @@ CONFIG_NLS_UTF8=m
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index 50092ba8aa7135e381403a2459dbf74f88ee96c0..e3e94c7e5ee1b6ff81bcd089658dff3dba2782f4 100644 (file)
@@ -162,6 +162,8 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT is not set
 CONFIG_PREEMPT_BKL=y
 # CONFIG_MIPS_INSANE_LARGE is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -980,6 +982,7 @@ CONFIG_SGI_PARTITION=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index dec2ba6ba03f428a2b72c0780d28ac9149e2255b..b4ab2bea972331c9f0d84544b9cbe9cd9899e3bb 100644 (file)
@@ -153,6 +153,8 @@ CONFIG_HZ=1000
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -922,6 +924,7 @@ CONFIG_SGI_PARTITION=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index 9f1e3048d62347417d464d32ec7cc9ef5fb8bea0..9d4d17ace123b50eacc4192b5c11fafba99e35a8 100644 (file)
@@ -153,6 +153,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -775,6 +777,7 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index fded3f73815feaf13cfda7e025d6056a5949b803..d03746667a96c6e390de1d7cef39585517e29ffa 100644 (file)
@@ -143,6 +143,8 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_RTC_DS1742=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -872,6 +874,7 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index 320b8cdd6e589e9bfbac7127c53bdff629693a2a..1db8249b4c0fa1aaafb33355137ee42c846e8b85 100644 (file)
@@ -151,6 +151,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -970,6 +972,7 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index 0ba1ef5048fb0a88a5cbf0c96619fb11cb0cab3d..aeefe2873e38fde99f986f266f93d6249eba533d 100644 (file)
@@ -170,6 +170,8 @@ CONFIG_HZ=100
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1341,6 +1343,7 @@ CONFIG_NLS_UTF8=m
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index adbeeadddb8f3da2bb16bd1270b4973793ef1cde..a3cbd23bf217d72ba338faf2cec97c3e1edd456a 100644 (file)
@@ -148,6 +148,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -799,6 +801,7 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index 79fd544fcb2a186b3ca0abcb5e8d4b319137a1cb..6570b47426cef5e326fa10d6dd22201da934b228 100644 (file)
@@ -148,6 +148,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
index 4d87da2b99fde8ee93cd2c14deff41256ce935bb..440d65f93a949bb6fbee4239b10caf9a57c7985a 100644 (file)
@@ -153,6 +153,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1091,6 +1093,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index a7ac2b0a8273a87ad46222717021bb316e96a331..c2c7ae77da3e68fc03562dab396f9e4499f46c6e 100644 (file)
@@ -150,6 +150,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -839,6 +841,7 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index 853e7bba5122e3294498a9224795b641c669370e..67efe270e0cc4cf6d3ee14db47ee357db8f54d02 100644 (file)
@@ -154,6 +154,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -788,6 +790,7 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index 8524efa23a490b7983c04d7149a6106728ca1109..a10f34de5f7ef5cc929dac8d5f33d726c70fe275 100644 (file)
@@ -153,6 +153,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -842,6 +844,7 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index 1a16e92900cbd9140f555f77a4f3d85eb791abb9..741f8258075c96ab27e2a284a0bb258f1654e089 100644 (file)
@@ -149,6 +149,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1000,6 +1002,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index 9ea8edea6f2934c03b553038e824a9d856ff5a0c..8576340714da703f2f81216d33f1a29e782cfa92 100644 (file)
@@ -148,6 +148,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1106,6 +1108,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index c4a158976f8f97209cc524b4ed14e23a322d249c..3db7427d1b5578d94c426226b66f530e474d5d1e 100644 (file)
@@ -148,6 +148,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1098,6 +1100,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index 1cbf270c301ce416b8d84300db216980cb04e302..26b0b9883496d8af2246a01f3b2f7c9ec8bc4e74 100644 (file)
@@ -153,6 +153,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -876,6 +878,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
index bec30b15b9bdc448225cdee4ca981ca87da62362..e93266b37dd918a9e752aba99dbcc1c503d52d90 100644 (file)
@@ -153,6 +153,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1057,6 +1059,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index f5f799e9370728d57f0f95dfc42c2f511e8c8b7b..9b0dab822bd0d3d63572c96889324214612e4b85 100644 (file)
@@ -145,6 +145,8 @@ CONFIG_HZ=100
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -733,6 +735,7 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index 2f5650227ba36aefbd454184f95f0f09699e2c9c..dd0296036026d3ed0f0fe5e194c7e65bdd783b3b 100644 (file)
@@ -155,6 +155,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1335,6 +1337,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index 4fee90b2b100920580610e49900c19f4a1ecb774..d8a498d64d625575812bdba03502cca0e03b3dc8 100644 (file)
@@ -158,6 +158,8 @@ CONFIG_HZ=1000
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1584,6 +1586,7 @@ CONFIG_NLS_UTF8=m
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index 9041f095f96fb892f7c0c04937040227c9e118b1..805a4fe450f5ea07329343687e8231d05163e6cf 100644 (file)
@@ -171,6 +171,8 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_PREEMPT_BKL=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -873,6 +875,7 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index 02abb2f1bfaf017b63f4379ffd52c02a9ca2ce00..6fcb656d8d87e69cada3001ffad816cc65cb787e 100644 (file)
@@ -151,6 +151,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -581,6 +583,7 @@ CONFIG_PARTITION_ADVANCED=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index ca3d0c4ba15b5861b4147bc08cd7af91b84cd291..dc312f19ada7ea36c8c87302bb5658312e9345f3 100644 (file)
@@ -151,6 +151,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1059,6 +1061,7 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index 4e2009ace278d7ce076074a089400caae5e99600..85615d99b01aeb63e552242ee3e3e9d9ab2c0631 100644 (file)
@@ -151,6 +151,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -968,6 +970,7 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index 535a813d01a932ba20936f3a71fdb6ceeb96111d..ad7271b3f2666dee49c35463b85ebf800cd23ac2 100644 (file)
@@ -151,6 +151,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1146,6 +1148,7 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index 3a3ef20b21cc0afbe9c13d6b6b1c70282dfd9eb3..863f6a7cadfd7b35008d59dae3cf0606990340b9 100644 (file)
@@ -147,6 +147,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
index e6b1dea5584245b12be1b1d688667ea8e0bc22bf..c10267d61cc90e36655c39e41953156b2c9dd030 100644 (file)
@@ -155,6 +155,8 @@ CONFIG_HZ=1000
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -829,6 +831,7 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
index 06a072b77b1c963a75a620da8fc6563c4eb6e1d8..4d3c1329f3cf8e4b0b66f8797d6f67e29c199c2a 100644 (file)
@@ -152,6 +152,8 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_PREEMPT_BKL=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -760,6 +762,7 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/dec/boot/Makefile b/arch/mips/dec/boot/Makefile
deleted file mode 100644 (file)
index bcea416..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# Makefile for the DECstation family specific parts of the kernel
-#
-
-netboot: all
-       $(LD) -N -G 0 -T ld.ecoff ../../boot/zImage \
-               dec_boot.o ramdisk.img -o nbImage
-
-obj-y   := decstation.o
-
-clean:
-       rm -f nbImage
diff --git a/arch/mips/dec/boot/decstation.c b/arch/mips/dec/boot/decstation.c
deleted file mode 100644 (file)
index 4db8bac..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * arch/mips/dec/decstation.c
- */
-#include <asm/sections.h>
-
-#define RELOC
-#define INITRD
-#define DEBUG_BOOT
-
-/*
- * Magic number indicating REX PROM available on DECSTATION.
- */
-#define        REX_PROM_MAGIC          0x30464354
-
-#define REX_PROM_CLEARCACHE    0x7c/4
-#define REX_PROM_PRINTF                0x30/4
-
-#define VEC_RESET              0xBFC00000              /* Prom base address */
-#define        PMAX_PROM_ENTRY(x)      (VEC_RESET+((x)*8))     /* Prom jump table */
-#define        PMAX_PROM_PRINTF        PMAX_PROM_ENTRY(17)
-
-#define PARAM  (k_start + 0x2000)
-
-#define LOADER_TYPE (*(unsigned char *) (PARAM+0x210))
-#define INITRD_START (*(unsigned long *) (PARAM+0x218))
-#define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c))
-
-extern int _ftext;                     /* begin and end of kernel image */
-extern void kernel_entry(int, char **, unsigned long, int *);
-
-void * memcpy(void * dest, const void *src, unsigned int count)
-{
-       unsigned long *tmp = (unsigned long *) dest, *s = (unsigned long *) src;
-
-       count >>= 2;
-       while (count--)
-               *tmp++ = *s++;
-
-       return dest;
-}
-
-void dec_entry(int argc, char **argv,
-              unsigned long magic, int *prom_vec)
-{
-       void (*rex_clear_cache)(void);
-       int (*prom_printf)(char *, ...);
-       unsigned long k_start, len;
-
-       /*
-        * The DS5100 leaves cpu with BEV enabled, clear it.
-        */
-       asm(    "lui\t$8,0x3000\n\t"
-               "mtc0\t$8,$12\n\t"
-               ".section\t.sdata\n\t"
-               ".section\t.sbss\n\t"
-               ".section\t.text"
-               : : : "$8");
-
-#ifdef DEBUG_BOOT
-       if (magic == REX_PROM_MAGIC) {
-       prom_printf = (int (*)(char *, ...)) *(prom_vec + REX_PROM_PRINTF);
-       } else {
-               prom_printf = (int (*)(char *, ...)) PMAX_PROM_PRINTF;
-       }
-       prom_printf("Launching kernel...\n");
-#endif
-
-       k_start = (unsigned long) (&kernel_entry) & 0xffff0000;
-
-#ifdef RELOC
-       /*
-        * Now copy kernel image to its destination.
-        */
-       len = ((unsigned long) (&_end) - k_start);
-       memcpy((void *)k_start, &_ftext, len);
-#endif
-
-       if (magic == REX_PROM_MAGIC) {
-               rex_clear_cache = (void (*)(void)) * (prom_vec + REX_PROM_CLEARCACHE);
-               rex_clear_cache();
-       }
-
-       kernel_entry(argc, argv, magic, prom_vec);
-}
diff --git a/arch/mips/dec/boot/ld.ecoff b/arch/mips/dec/boot/ld.ecoff
deleted file mode 100644 (file)
index aaa633d..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-OUTPUT_FORMAT("ecoff-littlemips")
-OUTPUT_ARCH(mips)
-ENTRY(dec_entry)
-SECTIONS
-{
-  . = 0x80200000;
-
-  .text :
-  {
-    _ftext = .;
-    *(.text)
-    *(.fixup)
-  }
-  .rdata :
-  {
-    *(.rodata .rodata.* .rdata)
-  }
-  .data :
-  {
-    . = ALIGN(0x1000);
-    ramdisk.img (.data)
-    *(.data)
-  }
-  .sdata :
-  {
-    *(.sdata)
-  }
-  _gp = .;
-  .sbss :
-  {
-    *(.sbss)
-    *(.scommon)
-  }
-  .bss :
-  {
-   *(.dynbss)
-   *(.bss)
-   *(COMMON)
-  }
-  /DISCARD/ : {
-    *(.reginfo .mdebug .note)
-  }
-}
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 57294740c2dd2bd9130a5763fdc3f195c36723ef..4cf0c06e2414b556d66cf5d8c212b4f28c523c0e 100644 (file)
@@ -184,8 +184,6 @@ void __init dec_time_init(void)
        CMOS_WRITE(RTC_REF_CLCK_32KHZ | (16 - __ffs(HZ)), RTC_REG_A);
 }
 
-EXPORT_SYMBOL(do_settimeofday);
-
 void __init plat_timer_setup(struct irqaction *irq)
 {
        setup_irq(dec_interrupt[DEC_IRQ_RTC], irq);
index cc9b24eda9e89480f17b0ddfb09d506d86febdae..21d53e0c9ee84c5126881129026a9224eddcdd20 100644 (file)
@@ -153,6 +153,8 @@ CONFIG_HZ=1000
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -1147,6 +1149,7 @@ CONFIG_NLS_UTF8=m
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
diff --git a/arch/mips/ite-boards/Kconfig b/arch/mips/ite-boards/Kconfig
deleted file mode 100644 (file)
index a6d59ad..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-config IT8172_REVC
-       bool "Support for older IT8172 (Rev C)"
-       depends on MIPS_ITE8172
-       help
-         Say Y here to support the older, Revision C version of the Integrated
-         Technology Express, Inc. ITE8172 SBC.  Vendor page at
-         <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
-         board at <http://www.mvista.com/partners/semiconductor/ite.html>.
diff --git a/arch/mips/ite-boards/generic/Makefile b/arch/mips/ite-boards/generic/Makefile
deleted file mode 100644 (file)
index 6343153..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-#  Copyright 2000 MontaVista Software Inc.
-#  Author: MontaVista Software, Inc.
-#      ppopov@mvista.com or source@mvista.com
-#
-# Makefile for the ITE 8172 (qed-4n-s01b) board, generic files.
-#
-
-obj-y                  += it8172_setup.o irq.o pmon_prom.o \
-                          time.o lpc.o puts.o reset.o
-
-obj-$(CONFIG_IT8172_CIR)+= it8172_cir.o
-obj-$(CONFIG_KGDB)     += dbg_io.o
-
-EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/ite-boards/generic/dbg_io.c b/arch/mips/ite-boards/generic/dbg_io.c
deleted file mode 100644 (file)
index 8e9cd8a..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-
-
-#ifdef CONFIG_KGDB
-
-/* --- CONFIG --- */
-
-/* we need uint32 uint8 */
-/* #include "types.h" */
-typedef unsigned char uint8;
-typedef unsigned int uint32;
-
-/* --- END OF CONFIG --- */
-
-#define         UART16550_BAUD_2400             2400
-#define         UART16550_BAUD_4800             4800
-#define         UART16550_BAUD_9600             9600
-#define         UART16550_BAUD_19200            19200
-#define         UART16550_BAUD_38400            38400
-#define         UART16550_BAUD_57600            57600
-#define         UART16550_BAUD_115200           115200
-
-#define         UART16550_PARITY_NONE           0
-#define         UART16550_PARITY_ODD            0x08
-#define         UART16550_PARITY_EVEN           0x18
-#define         UART16550_PARITY_MARK           0x28
-#define         UART16550_PARITY_SPACE          0x38
-
-#define         UART16550_DATA_5BIT             0x0
-#define         UART16550_DATA_6BIT             0x1
-#define         UART16550_DATA_7BIT             0x2
-#define         UART16550_DATA_8BIT             0x3
-
-#define         UART16550_STOP_1BIT             0x0
-#define         UART16550_STOP_2BIT             0x4
-
-/* ----------------------------------------------------- */
-
-/* === CONFIG === */
-
-/* [stevel] we use the IT8712 serial port for kgdb */
-#define        DEBUG_BASE  0xB40003F8  /* 8712 serial port 1 base address */
-#define MAX_BAUD    115200
-
-/* === END OF CONFIG === */
-
-/* register offset */
-#define         OFS_RCV_BUFFER          0
-#define         OFS_TRANS_HOLD          0
-#define         OFS_SEND_BUFFER         0
-#define         OFS_INTR_ENABLE         1
-#define         OFS_INTR_ID             2
-#define         OFS_DATA_FORMAT         3
-#define         OFS_LINE_CONTROL        3
-#define         OFS_MODEM_CONTROL       4
-#define         OFS_RS232_OUTPUT        4
-#define         OFS_LINE_STATUS         5
-#define         OFS_MODEM_STATUS        6
-#define         OFS_RS232_INPUT         6
-#define         OFS_SCRATCH_PAD         7
-
-#define         OFS_DIVISOR_LSB         0
-#define         OFS_DIVISOR_MSB         1
-
-
-/* memory-mapped read/write of the port */
-#define UART16550_READ(y)    (*((volatile uint8*)(DEBUG_BASE + y)))
-#define UART16550_WRITE(y,z) ((*((volatile uint8*)(DEBUG_BASE + y))) = z)
-
-void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
-{
-       /* disable interrupts */
-       UART16550_WRITE(OFS_INTR_ENABLE, 0);
-
-       /* set up baud rate */
-       {
-               uint32 divisor;
-
-               /* set DIAB bit */
-               UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
-
-               /* set divisor */
-               divisor = MAX_BAUD / baud;
-               UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
-               UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
-
-               /* clear DIAB bit */
-               UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
-       }
-
-       /* set data format */
-       UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
-}
-
-static int remoteDebugInitialized = 0;
-
-uint8 getDebugChar(void)
-{
-       if (!remoteDebugInitialized) {
-               remoteDebugInitialized = 1;
-               debugInit(UART16550_BAUD_115200,
-                         UART16550_DATA_8BIT,
-                         UART16550_PARITY_NONE, UART16550_STOP_1BIT);
-       }
-
-       while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
-       return UART16550_READ(OFS_RCV_BUFFER);
-}
-
-
-int putDebugChar(uint8 byte)
-{
-       if (!remoteDebugInitialized) {
-               remoteDebugInitialized = 1;
-               debugInit(UART16550_BAUD_115200,
-                         UART16550_DATA_8BIT,
-                         UART16550_PARITY_NONE, UART16550_STOP_1BIT);
-       }
-
-       while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
-       UART16550_WRITE(OFS_SEND_BUFFER, byte);
-       return 1;
-}
-
-#endif
diff --git a/arch/mips/ite-boards/generic/irq.c b/arch/mips/ite-boards/generic/irq.c
deleted file mode 100644 (file)
index cb59ca4..0000000
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- *     ITE 8172G interrupt/setup routines.
- *
- * Copyright 2000,2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
- *
- * Part of this file was derived from Carsten Langgaard's
- * arch/mips/mips-boards/atlas/atlas_int.c.
- *
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  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.
- */
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/kernel_stat.h>
-#include <linux/module.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/timex.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/serial_reg.h>
-#include <linux/bitops.h>
-
-#include <asm/bootinfo.h>
-#include <asm/io.h>
-#include <asm/mipsregs.h>
-#include <asm/system.h>
-#include <asm/it8172/it8172.h>
-#include <asm/it8172/it8172_int.h>
-#include <asm/it8172/it8172_dbg.h>
-
-/* revisit */
-#define EXT_IRQ0_TO_IP 2 /* IP 2 */
-#define EXT_IRQ5_TO_IP 7 /* IP 7 */
-
-#define ALLINTS_NOTIMER (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4)
-
-extern void set_debug_traps(void);
-extern void mips_timer_interrupt(int irq, struct pt_regs *regs);
-
-struct it8172_intc_regs volatile *it8172_hw0_icregs =
-       (struct it8172_intc_regs volatile *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_INTC_BASE));
-
-static void disable_it8172_irq(unsigned int irq_nr)
-{
-       if ( (irq_nr >= IT8172_LPC_IRQ_BASE) && (irq_nr <= IT8172_SERIRQ_15)) {
-               /* LPC interrupt */
-               it8172_hw0_icregs->lpc_mask |=
-                       (1 << (irq_nr - IT8172_LPC_IRQ_BASE));
-       } else if ( (irq_nr >= IT8172_LB_IRQ_BASE) && (irq_nr <= IT8172_IOCHK_IRQ)) {
-               /* Local Bus interrupt */
-               it8172_hw0_icregs->lb_mask |=
-                       (1 << (irq_nr - IT8172_LB_IRQ_BASE));
-       } else if ( (irq_nr >= IT8172_PCI_DEV_IRQ_BASE) && (irq_nr <= IT8172_DMA_IRQ)) {
-               /* PCI and other interrupts */
-               it8172_hw0_icregs->pci_mask |=
-                       (1 << (irq_nr - IT8172_PCI_DEV_IRQ_BASE));
-       } else if ( (irq_nr >= IT8172_NMI_IRQ_BASE) && (irq_nr <= IT8172_POWER_NMI_IRQ)) {
-               /* NMI interrupts */
-               it8172_hw0_icregs->nmi_mask |=
-                       (1 << (irq_nr - IT8172_NMI_IRQ_BASE));
-       } else {
-               panic("disable_it8172_irq: bad irq %d", irq_nr);
-       }
-}
-
-static void enable_it8172_irq(unsigned int irq_nr)
-{
-       if ( (irq_nr >= IT8172_LPC_IRQ_BASE) && (irq_nr <= IT8172_SERIRQ_15)) {
-               /* LPC interrupt */
-               it8172_hw0_icregs->lpc_mask &=
-                       ~(1 << (irq_nr - IT8172_LPC_IRQ_BASE));
-       }
-       else if ( (irq_nr >= IT8172_LB_IRQ_BASE) && (irq_nr <= IT8172_IOCHK_IRQ)) {
-               /* Local Bus interrupt */
-               it8172_hw0_icregs->lb_mask &=
-                       ~(1 << (irq_nr - IT8172_LB_IRQ_BASE));
-       }
-       else if ( (irq_nr >= IT8172_PCI_DEV_IRQ_BASE) && (irq_nr <= IT8172_DMA_IRQ)) {
-               /* PCI and other interrupts */
-               it8172_hw0_icregs->pci_mask &=
-                       ~(1 << (irq_nr - IT8172_PCI_DEV_IRQ_BASE));
-       }
-       else if ( (irq_nr >= IT8172_NMI_IRQ_BASE) && (irq_nr <= IT8172_POWER_NMI_IRQ)) {
-               /* NMI interrupts */
-               it8172_hw0_icregs->nmi_mask &=
-                       ~(1 << (irq_nr - IT8172_NMI_IRQ_BASE));
-       }
-       else {
-               panic("enable_it8172_irq: bad irq %d", irq_nr);
-       }
-}
-
-static unsigned int startup_ite_irq(unsigned int irq)
-{
-       enable_it8172_irq(irq);
-       return 0;
-}
-
-#define shutdown_ite_irq       disable_it8172_irq
-#define mask_and_ack_ite_irq    disable_it8172_irq
-
-static void end_ite_irq(unsigned int irq)
-{
-       if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-               enable_it8172_irq(irq);
-}
-
-static struct irq_chip it8172_irq_type = {
-       .typename = "ITE8172",
-       .startup = startup_ite_irq,
-       .shutdown = shutdown_ite_irq,
-       .enable = enable_it8172_irq,
-       .disable = disable_it8172_irq,
-       .ack = mask_and_ack_ite_irq,
-       .end = end_ite_irq,
-};
-
-
-static void enable_none(unsigned int irq) { }
-static unsigned int startup_none(unsigned int irq) { return 0; }
-static void disable_none(unsigned int irq) { }
-static void ack_none(unsigned int irq) { }
-
-/* startup is the same as "enable", shutdown is same as "disable" */
-#define shutdown_none  disable_none
-#define end_none       enable_none
-
-static struct irq_chip cp0_irq_type = {
-       .typename = "CP0 Count",
-       .startup = startup_none,
-       .shutdown = shutdown_none,
-       .enable = enable_none,
-       .disable = disable_none,
-       .ack = ack_none,
-       .end = end_none
-};
-
-void enable_cpu_timer(void)
-{
-        unsigned long flags;
-
-        local_irq_save(flags);
-       set_c0_status(0x100 << EXT_IRQ5_TO_IP);
-        local_irq_restore(flags);
-}
-
-void __init arch_init_irq(void)
-{
-       int i;
-        unsigned long flags;
-
-       /* mask all interrupts */
-       it8172_hw0_icregs->lb_mask  = 0xffff;
-       it8172_hw0_icregs->lpc_mask = 0xffff;
-       it8172_hw0_icregs->pci_mask = 0xffff;
-       it8172_hw0_icregs->nmi_mask = 0xffff;
-
-       /* make all interrupts level triggered */
-       it8172_hw0_icregs->lb_trigger  = 0;
-       it8172_hw0_icregs->lpc_trigger = 0;
-       it8172_hw0_icregs->pci_trigger = 0;
-       it8172_hw0_icregs->nmi_trigger = 0;
-
-       /* active level setting */
-       /* uart, keyboard, and mouse are active high */
-       it8172_hw0_icregs->lpc_level = (0x10 | 0x2 | 0x1000);
-       it8172_hw0_icregs->lb_level |= 0x20;
-
-       /* keyboard and mouse are edge triggered */
-       it8172_hw0_icregs->lpc_trigger |= (0x2 | 0x1000);
-
-
-#if 0
-       // Enable this piece of code to make internal USB interrupt
-       // edge triggered.
-       it8172_hw0_icregs->pci_trigger |=
-               (1 << (IT8172_USB_IRQ - IT8172_PCI_DEV_IRQ_BASE));
-       it8172_hw0_icregs->pci_level &=
-               ~(1 << (IT8172_USB_IRQ - IT8172_PCI_DEV_IRQ_BASE));
-#endif
-
-       for (i = 0; i <= IT8172_LAST_IRQ; i++) {
-               irq_desc[i].chip = &it8172_irq_type;
-               spin_lock_init(&irq_desc[i].lock);
-       }
-       irq_desc[MIPS_CPU_TIMER_IRQ].chip = &cp0_irq_type;
-       set_c0_status(ALLINTS_NOTIMER);
-}
-
-void mips_spurious_interrupt(struct pt_regs *regs)
-{
-#if 1
-       return;
-#else
-       unsigned long status, cause;
-
-       printk("got spurious interrupt\n");
-       status = read_c0_status();
-       cause = read_c0_cause();
-       printk("status %x cause %x\n", status, cause);
-       printk("epc %x badvaddr %x \n", regs->cp0_epc, regs->cp0_badvaddr);
-#endif
-}
-
-void it8172_hw0_irqdispatch(struct pt_regs *regs)
-{
-       int irq;
-       unsigned short intstatus = 0, status = 0;
-
-       intstatus = it8172_hw0_icregs->intstatus;
-       if (intstatus & 0x8) {
-               panic("Got NMI interrupt");
-       } else if (intstatus & 0x4) {
-               /* PCI interrupt */
-               irq = 0;
-               status |= it8172_hw0_icregs->pci_req;
-               while (!(status & 0x1)) {
-                       irq++;
-                       status >>= 1;
-               }
-               irq += IT8172_PCI_DEV_IRQ_BASE;
-       } else if (intstatus & 0x1) {
-               /* Local Bus interrupt */
-               irq = 0;
-               status |= it8172_hw0_icregs->lb_req;
-               while (!(status & 0x1)) {
-                       irq++;
-                       status >>= 1;
-               }
-               irq += IT8172_LB_IRQ_BASE;
-       } else if (intstatus & 0x2) {
-               /* LPC interrupt */
-               /* Since some lpc interrupts are edge triggered,
-                * we could lose an interrupt this way because
-                * we acknowledge all ints at onces. Revisit.
-                */
-               status |= it8172_hw0_icregs->lpc_req;
-               it8172_hw0_icregs->lpc_req = 0; /* acknowledge ints */
-               irq = 0;
-               while (!(status & 0x1)) {
-                       irq++;
-                       status >>= 1;
-               }
-               irq += IT8172_LPC_IRQ_BASE;
-       } else
-               return;
-
-       do_IRQ(irq, regs);
-}
-
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
-{
-       unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
-
-       if (!pending)
-               mips_spurious_interrupt(regs);
-       else if (pending & CAUSEF_IP7)
-               ll_timer_interrupt(127, regs);
-       else if (pending & CAUSEF_IP2)
-               it8172_hw0_irqdispatch(regs);
-}
-
-void show_pending_irqs(void)
-{
-       fputs("intstatus:  ");
-       put32(it8172_hw0_icregs->intstatus);
-       puts("");
-
-       fputs("pci_req:  ");
-       put32(it8172_hw0_icregs->pci_req);
-       puts("");
-
-       fputs("lb_req:  ");
-       put32(it8172_hw0_icregs->lb_req);
-       puts("");
-
-       fputs("lpc_req:  ");
-       put32(it8172_hw0_icregs->lpc_req);
-       puts("");
-}
diff --git a/arch/mips/ite-boards/generic/it8172_cir.c b/arch/mips/ite-boards/generic/it8172_cir.c
deleted file mode 100644 (file)
index bfc25ad..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *     IT8172 Consumer IR port generic routines.
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@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.
- */
-
-
-#ifdef CONFIG_IT8172_CIR
-
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <asm/it8172/it8172.h>
-#include <asm/it8172/it8172_cir.h>
-
-
-volatile struct it8172_cir_regs *cir_regs[NUM_CIR_PORTS] = {
-       (volatile struct it8172_cir_regs *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_CIR0_BASE)),
-       (volatile struct it8172_cir_regs *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_CIR1_BASE))};
-
-
-/*
- * Initialize Consumer IR Port.
- */
-int cir_port_init(struct cir_port *cir)
-{
-       int port = cir->port;
-       unsigned char data;
-
-       /* set baud rate */
-       cir_regs[port]->bdlr = cir->baud_rate & 0xff;
-       cir_regs[port]->bdhr = (cir->baud_rate >> 8) & 0xff;
-
-       /* set receiver control register */
-       cir_regs[port]->rcr = (CIR_SET_RDWOS(cir->rdwos) | CIR_SET_RXDCR(cir->rxdcr));
-
-       /* set carrier frequency register */
-       cir_regs[port]->cfr = (CIR_SET_CF(cir->cfq) | CIR_SET_HS(cir->hcfs));
-
-       /* set fifo threshold */
-       data = cir_regs[port]->mstcr & 0xf3;
-       data |= CIR_SET_FIFO_TL(cir->fifo_tl);
-       cir_regs[port]->mstcr = data;
-
-       clear_fifo(cir);
-       enable_receiver(cir);
-       disable_rx_demodulation(cir);
-
-       set_rx_active(cir);
-       int_enable(cir);
-       rx_int_enable(cir);
-
-       return 0;
-}
-
-
-void clear_fifo(struct cir_port *cir)
-{
-       cir_regs[cir->port]->mstcr |= CIR_FIFO_CLEAR;
-}
-
-void enable_receiver(struct cir_port *cir)
-{
-       cir_regs[cir->port]->rcr |= CIR_RXEN;
-}
-
-void disable_receiver(struct cir_port *cir)
-{
-       cir_regs[cir->port]->rcr &= ~CIR_RXEN;
-}
-
-void enable_rx_demodulation(struct cir_port *cir)
-{
-       cir_regs[cir->port]->rcr |= CIR_RXEND;
-}
-
-void disable_rx_demodulation(struct cir_port *cir)
-{
-       cir_regs[cir->port]->rcr &= ~CIR_RXEND;
-}
-
-void set_rx_active(struct cir_port *cir)
-{
-       cir_regs[cir->port]->rcr |= CIR_RXACT;
-}
-
-void int_enable(struct cir_port *cir)
-{
-       cir_regs[cir->port]->ier |= CIR_IEC;
-}
-
-void rx_int_enable(struct cir_port *cir)
-{
-       cir_regs[cir->port]->ier |= CIR_RDAIE;
-}
-
-void dump_regs(struct cir_port *cir)
-{
-       printk("mstcr %x ier %x iir %x cfr %x rcr %x tcr %x tfsr %x rfsr %x\n",
-       cir_regs[cir->port]->mstcr,
-       cir_regs[cir->port]->ier,
-       cir_regs[cir->port]->iir,
-       cir_regs[cir->port]->cfr,
-       cir_regs[cir->port]->rcr,
-       cir_regs[cir->port]->tcr,
-       cir_regs[cir->port]->tfsr,
-       cir_regs[cir->port]->rfsr);
-
-       while (cir_regs[cir->port]->iir & CIR_RDAI) {
-               printk("data %x\n", cir_regs[cir->port]->dr);
-       }
-}
-
-void dump_reg_addr(struct cir_port *cir)
-{
-       printk("dr %x mstcr %x ier %x iir %x cfr %x rcr %x tcr %x bdlr %x bdhr %x tfsr %x rfsr %x\n",
-       (unsigned)&cir_regs[cir->port]->dr,
-       (unsigned)&cir_regs[cir->port]->mstcr,
-       (unsigned)&cir_regs[cir->port]->ier,
-       (unsigned)&cir_regs[cir->port]->iir,
-       (unsigned)&cir_regs[cir->port]->cfr,
-       (unsigned)&cir_regs[cir->port]->rcr,
-       (unsigned)&cir_regs[cir->port]->tcr,
-       (unsigned)&cir_regs[cir->port]->bdlr,
-       (unsigned)&cir_regs[cir->port]->bdhr,
-       (unsigned)&cir_regs[cir->port]->tfsr,
-       (unsigned)&cir_regs[cir->port]->rfsr);
-}
-
-int cir_get_rx_count(struct cir_port *cir)
-{
-       return cir_regs[cir->port]->rfsr & CIR_RXFBC_MASK;
-}
-
-char cir_read_data(struct cir_port *cir)
-{
-       return cir_regs[cir->port]->dr;
-}
-
-char get_int_status(struct cir_port *cir)
-{
-       return cir_regs[cir->port]->iir;
-}
-#endif
diff --git a/arch/mips/ite-boards/generic/it8172_setup.c b/arch/mips/ite-boards/generic/it8172_setup.c
deleted file mode 100644 (file)
index 07faf3c..0000000
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- *     IT8172/QED5231 board setup.
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@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.
- */
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <linux/irq.h>
-#include <linux/serial_reg.h>
-#include <linux/major.h>
-#include <linux/kdev_t.h>
-#include <linux/root_dev.h>
-#include <linux/pm.h>
-
-#include <asm/cpu.h>
-#include <asm/time.h>
-#include <asm/io.h>
-#include <asm/bootinfo.h>
-#include <asm/irq.h>
-#include <asm/mipsregs.h>
-#include <asm/reboot.h>
-#include <asm/traps.h>
-#include <asm/it8172/it8172.h>
-#include <asm/it8712.h>
-
-extern struct resource ioport_resource;
-#ifdef CONFIG_SERIO_I8042
-int init_8712_keyboard(void);
-#endif
-
-extern int SearchIT8712(void);
-extern void InitLPCInterface(void);
-extern char * __init prom_getcmdline(void);
-extern void it8172_restart(char *command);
-extern void it8172_halt(void);
-extern void it8172_power_off(void);
-
-extern void it8172_time_init(void);
-
-#ifdef CONFIG_IT8172_REVC
-struct {
-    struct resource ram;
-    struct resource pci_mem;
-    struct resource pci_io;
-    struct resource flash;
-    struct resource boot;
-} it8172_resources = {
-       {
-               .start  = 0,                            /* to be initted */
-               .end    = 0,
-               .name   = "RAM",
-               .flags  = IORESOURCE_MEM
-       }, {
-               .start  = 0x10000000,
-               .end    = 0x13FFFFFF,
-               .name   = "PCI Mem",
-               .flags  = IORESOURCE_MEM
-       }, {
-               .start  = 0x14000000,
-               .end    = 0x17FFFFFF
-               .name   = "PCI I/O",
-       }, {
-               .start  = 0x08000000,
-               .end    = 0x0CFFFFFF
-               .name   = "Flash",
-       }, {
-               .start  = 0x1FC00000,
-               .end    = 0x1FFFFFFF
-               .name   = "Boot ROM",
-       }
-};
-#else
-struct {
-    struct resource ram;
-    struct resource pci_mem0;
-    struct resource pci_mem1;
-    struct resource pci_io;
-    struct resource pci_mem2;
-    struct resource pci_mem3;
-    struct resource flash;
-    struct resource boot;
-} it8172_resources = {
-       {
-               .start  = 0,                            /* to be initted */
-               .end    = 0,
-               .name   = "RAM",
-               .flags  = IORESOURCE_MEM
-       }, {
-               .start  = 0x0C000000,
-               .end    = 0x0FFFFFFF,
-               .name   = "PCI Mem0",
-               .flags  = IORESOURCE_MEM
-        }, {
-               .start  = 0x10000000,
-               .end    = 0x13FFFFFF,
-               .name   = "PCI Mem1",
-               .flags  = IORESOURCE_MEM
-        }, {
-               .start  = 0x14000000,
-               .end    = 0x17FFFFFF
-               .name   = "PCI I/O",
-       }, {
-               .start  = 0x1A000000,
-               .end    = 0x1BFFFFFF,
-               .name   = "PCI Mem2",
-               .flags  = IORESOURCE_MEM
-       }, {
-               .start  = 0x1C000000,
-               .end    = 0x1FBFFFFF,
-               .name   = "PCI Mem3",
-               .flags  = IORESOURCE_MEM
-       }, {
-               .start  = 0x08000000,
-               .end    = 0x0CFFFFFF
-               .name   = "Flash",
-       }, {
-               .start  = 0x1FC00000,
-               .end    = 0x1FFFFFFF
-               .name   = "Boot ROM",
-       }
-};
-#endif
-
-
-void __init it8172_init_ram_resource(unsigned long memsize)
-{
-       it8172_resources.ram.end = memsize;
-}
-
-void __init plat_mem_setup(void)
-{
-       unsigned short dsr;
-       char *argptr;
-
-       argptr = prom_getcmdline();
-#ifdef CONFIG_SERIAL_CONSOLE
-       if ((argptr = strstr(argptr, "console=")) == NULL) {
-               argptr = prom_getcmdline();
-               strcat(argptr, " console=ttyS0,115200");
-       }
-#endif
-
-       clear_c0_status(ST0_FR);
-
-       board_time_init = it8172_time_init;
-
-       _machine_restart = it8172_restart;
-       _machine_halt = it8172_halt;
-       pm_power_off = it8172_power_off;
-
-       /*
-        * IO/MEM resources.
-        *
-        * revisit this area.
-        */
-       set_io_port_base(KSEG1);
-       ioport_resource.start = it8172_resources.pci_io.start;
-       ioport_resource.end = it8172_resources.pci_io.end;
-#ifdef CONFIG_IT8172_REVC
-       iomem_resource.start = it8172_resources.pci_mem.start;
-       iomem_resource.end = it8172_resources.pci_mem.end;
-#else
-       iomem_resource.start = it8172_resources.pci_mem0.start;
-       iomem_resource.end = it8172_resources.pci_mem3.end;
-#endif
-
-#ifdef CONFIG_BLK_DEV_INITRD
-       ROOT_DEV = Root_RAM0;
-#endif
-
-       /*
-        * Pull enabled devices out of standby
-        */
-       IT_IO_READ16(IT_PM_DSR, dsr);
-
-       /*
-        * Fixme: This breaks when these drivers are modules!!!
-        */
-#ifdef CONFIG_SOUND_IT8172
-       dsr &= ~IT_PM_DSR_ACSB;
-#else
-       dsr |= IT_PM_DSR_ACSB;
-#endif
-#ifdef CONFIG_BLK_DEV_IT8172
-       dsr &= ~IT_PM_DSR_IDESB;
-#else
-       dsr |= IT_PM_DSR_IDESB;
-#endif
-       IT_IO_WRITE16(IT_PM_DSR, dsr);
-
-       InitLPCInterface();
-
-#ifdef CONFIG_MIPS_ITE8172
-       if (SearchIT8712()) {
-               printk("Found IT8712 Super IO\n");
-               /* enable IT8712 serial port */
-               LPCSetConfig(LDN_SERIAL1, 0x30, 0x01); /* enable */
-               LPCSetConfig(LDN_SERIAL1, 0x23, 0x01); /* clock selection */
-#ifdef CONFIG_SERIO_I8042
-               if (init_8712_keyboard()) {
-                       printk("Unable to initialize keyboard\n");
-                       LPCSetConfig(LDN_KEYBOARD, 0x30, 0x0); /* disable keyboard */
-               } else {
-                       LPCSetConfig(LDN_KEYBOARD, 0x30, 0x1); /* enable keyboard */
-                       LPCSetConfig(LDN_KEYBOARD, 0xf0, 0x2);
-                       LPCSetConfig(LDN_KEYBOARD, 0x71, 0x3);
-
-                       LPCSetConfig(LDN_MOUSE, 0x30, 0x1); /* enable mouse */
-
-                       LPCSetConfig(0x4, 0x30, 0x1);
-                       LPCSetConfig(0x4, 0xf4, LPCGetConfig(0x4, 0xf4) | 0x80);
-
-                       if ((LPCGetConfig(LDN_KEYBOARD, 0x30) == 0) ||
-                                       (LPCGetConfig(LDN_MOUSE, 0x30) == 0))
-                               printk("Error: keyboard or mouse not enabled\n");
-
-               }
-#endif
-       }
-       else {
-               printk("IT8712 Super IO not found\n");
-       }
-#endif
-
-#ifdef CONFIG_IT8172_CIR
-       {
-               unsigned long data;
-               //printk("Enabling CIR0\n");
-               IT_IO_READ16(IT_PM_DSR, data);
-               data &= ~IT_PM_DSR_CIR0SB;
-               IT_IO_WRITE16(IT_PM_DSR, data);
-               //printk("DSR register: %x\n", (unsigned)IT_IO_READ16(IT_PM_DSR, data));
-       }
-#endif
-#ifdef CONFIG_IT8172_SCR0
-       {
-               unsigned i;
-               /* Enable Smart Card Reader 0 */
-               /* First power it up */
-               IT_IO_READ16(IT_PM_DSR, i);
-               i &= ~IT_PM_DSR_SCR0SB;
-               IT_IO_WRITE16(IT_PM_DSR, i);
-               /* Then initialize its registers */
-               outb(( IT_SCR_SFR_GATE_UART_OFF     << IT_SCR_SFR_GATE_UART_BIT
-                     |IT_SCR_SFR_FET_CHARGE_213_US << IT_SCR_SFR_FET_CHARGE_BIT
-                     |IT_SCR_SFR_CARD_FREQ_3_5_MHZ << IT_SCR_SFR_CARD_FREQ_BIT
-                     |IT_SCR_SFR_FET_ACTIVE_INVERT << IT_SCR_SFR_FET_ACTIVE_BIT
-                     |IT_SCR_SFR_ENABLE_ON         << IT_SCR_SFR_ENABLE_BIT),
-                    IT8172_PCI_IO_BASE + IT_SCR0_BASE + IT_SCR_SFR);
-               outb(IT_SCR_SCDR_RESET_MODE_ASYNC << IT_SCR_SCDR_RESET_MODE_BIT,
-                    IT8172_PCI_IO_BASE + IT_SCR0_BASE + IT_SCR_SCDR);
-       }
-#endif /* CONFIG_IT8172_SCR0 */
-#ifdef CONFIG_IT8172_SCR1
-       {
-               unsigned i;
-               /* Enable Smart Card Reader 1 */
-               /* First power it up */
-               IT_IO_READ16(IT_PM_DSR, i);
-               i &= ~IT_PM_DSR_SCR1SB;
-               IT_IO_WRITE16(IT_PM_DSR, i);
-               /* Then initialize its registers */
-               outb(( IT_SCR_SFR_GATE_UART_OFF     << IT_SCR_SFR_GATE_UART_BIT
-                     |IT_SCR_SFR_FET_CHARGE_213_US << IT_SCR_SFR_FET_CHARGE_BIT
-                     |IT_SCR_SFR_CARD_FREQ_3_5_MHZ << IT_SCR_SFR_CARD_FREQ_BIT
-                     |IT_SCR_SFR_FET_ACTIVE_INVERT << IT_SCR_SFR_FET_ACTIVE_BIT
-                     |IT_SCR_SFR_ENABLE_ON         << IT_SCR_SFR_ENABLE_BIT),
-                    IT8172_PCI_IO_BASE + IT_SCR1_BASE + IT_SCR_SFR);
-               outb(IT_SCR_SCDR_RESET_MODE_ASYNC << IT_SCR_SCDR_RESET_MODE_BIT,
-                    IT8172_PCI_IO_BASE + IT_SCR1_BASE + IT_SCR_SCDR);
-       }
-#endif /* CONFIG_IT8172_SCR1 */
-}
-
-#ifdef CONFIG_SERIO_I8042
-/*
- * According to the ITE Special BIOS Note for waking up the
- * keyboard controller...
- */
-static int init_8712_keyboard(void)
-{
-       unsigned int cmd_port = 0x14000064;
-       unsigned int data_port = 0x14000060;
-                                ^^^^^^^^^^^
-       Somebody here doesn't grok the concept of io ports.
-
-       unsigned char data;
-       int i;
-
-       outb(0xaa, cmd_port); /* send self-test cmd */
-       i = 0;
-       while (!(inb(cmd_port) & 0x1)) { /* wait output buffer full */
-               i++;
-               if (i > 0xffffff)
-                       return 1;
-       }
-
-       data = inb(data_port);
-       outb(0xcb, cmd_port); /* set ps2 mode */
-       while (inb(cmd_port) & 0x2) { /* wait while input buffer full */
-               i++;
-               if (i > 0xffffff)
-                       return 1;
-       }
-       outb(0x01, data_port);
-       while (inb(cmd_port) & 0x2) { /* wait while input buffer full */
-               i++;
-               if (i > 0xffffff)
-                       return 1;
-       }
-
-       outb(0x60, cmd_port); /* write 8042 command byte */
-       while (inb(cmd_port) & 0x2) { /* wait while input buffer full */
-               i++;
-               if (i > 0xffffff)
-                       return 1;
-       }
-       outb(0x45, data_port); /* at interface, keyboard enabled, system flag */
-       while (inb(cmd_port) & 0x2) { /* wait while input buffer full */
-               i++;
-               if (i > 0xffffff)
-                       return 1;
-       }
-
-       outb(0xae, cmd_port); /* enable interface */
-       return 0;
-}
-#endif
diff --git a/arch/mips/ite-boards/generic/lpc.c b/arch/mips/ite-boards/generic/lpc.c
deleted file mode 100644 (file)
index cc7584f..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *     ITE Semi IT8712 Super I/O functions.
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@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.
- */
-
-#include <asm/io.h>
-#include <asm/types.h>
-#include <asm/it8712.h>
-#include <asm/it8172/it8172.h>
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-void LPCEnterMBPnP(void)
-{
-       int i;
-       unsigned char key[4] = {0x87, 0x01, 0x55, 0x55};
-
-       for (i = 0; i<4; i++)
-               outb(key[i], LPC_KEY_ADDR);
-
-}
-
-void LPCExitMBPnP(void)
-{
-       outb(0x02, LPC_KEY_ADDR);
-       outb(0x02, LPC_DATA_ADDR);
-}
-
-void LPCSetConfig(char LdnNumber, char Index, char data)
-{
-       LPCEnterMBPnP();                                // Enter IT8712 MB PnP mode
-       outb(0x07, LPC_KEY_ADDR);
-       outb(LdnNumber, LPC_DATA_ADDR);
-       outb(Index, LPC_KEY_ADDR);
-       outb(data, LPC_DATA_ADDR);
-       LPCExitMBPnP();
-}
-
-char LPCGetConfig(char LdnNumber, char Index)
-{
-       char rtn;
-
-       LPCEnterMBPnP();                                // Enter IT8712 MB PnP mode
-       outb(0x07, LPC_KEY_ADDR);
-       outb(LdnNumber, LPC_DATA_ADDR);
-       outb(Index, LPC_KEY_ADDR);
-       rtn = inb(LPC_DATA_ADDR);
-       LPCExitMBPnP();
-       return rtn;
-}
-
-int SearchIT8712(void)
-{
-       unsigned char Id1, Id2;
-       unsigned short Id;
-
-       LPCEnterMBPnP();
-       outb(0x20, LPC_KEY_ADDR); /* chip id byte 1 */
-       Id1 = inb(LPC_DATA_ADDR);
-       outb(0x21, LPC_KEY_ADDR); /* chip id byte 2 */
-       Id2 = inb(LPC_DATA_ADDR);
-       Id = (Id1 << 8) | Id2;
-       LPCExitMBPnP();
-       if (Id == 0x8712)
-               return TRUE;
-       else
-               return FALSE;
-}
-
-void InitLPCInterface(void)
-{
-       unsigned char bus, dev_fn;
-       unsigned long data;
-
-       bus = 0;
-       dev_fn = 1<<3 | 4;
-
-
-       /* pci cmd, SERR# Enable */
-       IT_WRITE(IT_CONFADDR,
-                (bus         << IT_BUSNUM_SHF)   |
-                (dev_fn      << IT_FUNCNUM_SHF) |
-                ((0x4 / 4) << IT_REGNUM_SHF));
-       IT_READ(IT_CONFDATA, data);
-       data |= 0x0100;
-       IT_WRITE(IT_CONFADDR,
-                (bus         << IT_BUSNUM_SHF)   |
-                (dev_fn      << IT_FUNCNUM_SHF) |
-                ((0x4 / 4) << IT_REGNUM_SHF));
-       IT_WRITE(IT_CONFDATA, data);
-
-       /* setup serial irq control register */
-       IT_WRITE(IT_CONFADDR,
-                (bus         << IT_BUSNUM_SHF)   |
-                (dev_fn      << IT_FUNCNUM_SHF) |
-                ((0x48 / 4) << IT_REGNUM_SHF));
-       IT_READ(IT_CONFDATA, data);
-       data  = (data & 0xffff00ff) | 0xc400;
-       IT_WRITE(IT_CONFADDR,
-                (bus         << IT_BUSNUM_SHF)   |
-                (dev_fn      << IT_FUNCNUM_SHF) |
-                ((0x48 / 4) << IT_REGNUM_SHF));
-       IT_WRITE(IT_CONFDATA, data);
-
-
-       /* Enable I/O Space Subtractive Decode */
-       /* default 0x4C is 0x3f220000 */
-       IT_WRITE(IT_CONFADDR,
-                (bus         << IT_BUSNUM_SHF)   |
-                (dev_fn      << IT_FUNCNUM_SHF) |
-                ((0x4C / 4) << IT_REGNUM_SHF));
-       IT_WRITE(IT_CONFDATA, 0x3f2200f3);
-}
diff --git a/arch/mips/ite-boards/generic/pmon_prom.c b/arch/mips/ite-boards/generic/pmon_prom.c
deleted file mode 100644 (file)
index 7d0a79b..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *    PROM library initialisation code, assuming a version of
- *    pmon is the boot code.
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
- *
- * This file was derived from Carsten Langgaard's
- * arch/mips/mips-boards/xx files.
- *
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  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.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/string.h>
-
-#include <asm/bootinfo.h>
-
-extern int prom_argc;
-extern char **prom_argv, **prom_envp;
-
-typedef struct
-{
-    char *name;
-/*    char *val; */
-}t_env_var;
-
-
-char * __init prom_getcmdline(void)
-{
-       return &(arcs_cmdline[0]);
-}
-
-void  __init prom_init_cmdline(void)
-{
-       char *cp;
-       int actr;
-
-       actr = 1; /* Always ignore argv[0] */
-
-       cp = &(arcs_cmdline[0]);
-       while(actr < prom_argc) {
-               strcpy(cp, prom_argv[actr]);
-               cp += strlen(prom_argv[actr]);
-               *cp++ = ' ';
-               actr++;
-       }
-       if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
-               --cp;
-       *cp = '\0';
-
-}
-
-
-char *prom_getenv(char *envname)
-{
-       /*
-        * Return a pointer to the given environment variable.
-        * Environment variables are stored in the form of "memsize=64".
-        */
-
-       t_env_var *env = (t_env_var *)prom_envp;
-       int i;
-
-       i = strlen(envname);
-
-       while(env->name) {
-               if(strncmp(envname, env->name, i) == 0) {
-                       return(env->name + strlen(envname) + 1);
-               }
-               env++;
-       }
-       return(NULL);
-}
-
-static inline unsigned char str2hexnum(unsigned char c)
-{
-       if(c >= '0' && c <= '9')
-       return c - '0';
-       if(c >= 'a' && c <= 'f')
-       return c - 'a' + 10;
-       return 0; /* foo */
-}
-
-unsigned long __init prom_free_prom_memory(void)
-{
-       return 0;
-}
-
-unsigned long __init prom_get_memsize(void)
-{
-       char *memsize_str;
-       unsigned int memsize;
-
-       memsize_str = prom_getenv("memsize");
-       if (!memsize_str) {
-#ifdef CONFIG_MIPS_ITE8172
-               memsize = 32;
-#elif defined(CONFIG_MIPS_IVR)
-               memsize = 64;
-#else
-               memsize = 8;
-#endif
-               printk("memsize unknown: setting to %dMB\n", memsize);
-       } else {
-               printk("memsize: %s\n", memsize_str);
-               memsize = simple_strtol(memsize_str, NULL, 0);
-       }
-       return memsize;
-}
diff --git a/arch/mips/ite-boards/generic/puts.c b/arch/mips/ite-boards/generic/puts.c
deleted file mode 100644 (file)
index 20b02df..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *     Low level uart routines to directly access a 16550 uart.
- *
- * Copyright 2000,2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@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.
- */
-
-#include <linux/types.h>
-
-#define SERIAL_BASE   0xB4011800       /* it8172 */
-#define SER_CMD       5
-#define SER_DATA      0x00
-#define TX_BUSY       0x20
-
-#define TIMEOUT       0xffff
-#undef SLOW_DOWN
-
-static const char digits[16] = "0123456789abcdef";
-static volatile unsigned char *const com1 = (unsigned char *) SERIAL_BASE;
-
-
-#ifdef SLOW_DOWN
-static inline void slow_down()
-{
-       int k;
-       for (k = 0; k < 10000; k++);
-}
-#else
-#define slow_down()
-#endif
-
-void putch(const unsigned char c)
-{
-       unsigned char ch;
-       int i = 0;
-
-       do {
-               ch = com1[SER_CMD];
-               slow_down();
-               i++;
-               if (i > TIMEOUT) {
-                       break;
-               }
-       } while (0 == (ch & TX_BUSY));
-       com1[SER_DATA] = c;
-}
-
-void puts(unsigned char *cp)
-{
-       unsigned char ch;
-       int i = 0;
-
-       while (*cp) {
-               do {
-                       ch = com1[SER_CMD];
-                       slow_down();
-                       i++;
-                       if (i > TIMEOUT) {
-                               break;
-                       }
-               } while (0 == (ch & TX_BUSY));
-               com1[SER_DATA] = *cp++;
-       }
-       putch('\r');
-       putch('\n');
-}
-
-void fputs(unsigned char *cp)
-{
-       unsigned char ch;
-       int i = 0;
-
-       while (*cp) {
-
-               do {
-                       ch = com1[SER_CMD];
-                       slow_down();
-                       i++;
-                       if (i > TIMEOUT) {
-                               break;
-                       }
-               } while (0 == (ch & TX_BUSY));
-               com1[SER_DATA] = *cp++;
-       }
-}
-
-
-void put64(uint64_t ul)
-{
-       int cnt;
-       unsigned ch;
-
-       cnt = 16;               /* 16 nibbles in a 64 bit long */
-       putch('0');
-       putch('x');
-       do {
-               cnt--;
-               ch = (unsigned char) (ul >> cnt * 4) & 0x0F;
-               putch(digits[ch]);
-       } while (cnt > 0);
-}
-
-void put32(unsigned u)
-{
-       int cnt;
-       unsigned ch;
-
-       cnt = 8;                /* 8 nibbles in a 32 bit long */
-       putch('0');
-       putch('x');
-       do {
-               cnt--;
-               ch = (unsigned char) (u >> cnt * 4) & 0x0F;
-               putch(digits[ch]);
-       } while (cnt > 0);
-}
diff --git a/arch/mips/ite-boards/generic/reset.c b/arch/mips/ite-boards/generic/reset.c
deleted file mode 100644 (file)
index 03bd5ba..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *     ITE 8172 reset routines.
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@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.
- */
-
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <asm/cacheflush.h>
-#include <asm/io.h>
-#include <asm/processor.h>
-#include <asm/reboot.h>
-#include <asm/system.h>
-
-void it8172_restart()
-{
-       set_c0_status(ST0_BEV | ST0_ERL);
-       change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
-       flush_cache_all();
-       write_c0_wired(0);
-       __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
-}
-
-void it8172_halt(void)
-{
-       printk(KERN_NOTICE "\n** You can safely turn off the power\n");
-       while (1)
-               __asm__(".set\tmips3\n\t"
-                       "wait\n\t"
-                       ".set\tmips0");
-}
-
-void it8172_power_off(void)
-{
-       it8172_halt();
-}
diff --git a/arch/mips/ite-boards/generic/time.c b/arch/mips/ite-boards/generic/time.c
deleted file mode 100644 (file)
index 3dc5556..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * Copyright (C) 2003 MontaVista Software Inc.
- * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute 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 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.
- *
- * ########################################################################
- *
- * Setting up the clock on the MIPS boards.
- */
-#include <linux/init.h>
-#include <linux/kernel_stat.h>
-#include <linux/sched.h>
-#include <linux/time.h>
-#include <linux/spinlock.h>
-#include <linux/mc146818rtc.h>
-
-#include <asm/time.h>
-#include <asm/mipsregs.h>
-#include <asm/ptrace.h>
-#include <asm/it8172/it8172.h>
-#include <asm/it8172/it8172_int.h>
-#include <asm/debug.h>
-
-#define IT8172_RTC_ADR_REG  (IT8172_PCI_IO_BASE + IT_RTC_BASE)
-#define IT8172_RTC_DAT_REG  (IT8172_RTC_ADR_REG + 1)
-#define IT8172_RTC_CENTURY_REG  (IT8172_PCI_IO_BASE + IT_RTC_CENTURY)
-
-static volatile char *rtc_adr_reg = (char*)KSEG1ADDR(IT8172_RTC_ADR_REG);
-static volatile char *rtc_dat_reg = (char*)KSEG1ADDR(IT8172_RTC_DAT_REG);
-static volatile char *rtc_century_reg = (char*)KSEG1ADDR(IT8172_RTC_CENTURY_REG);
-
-unsigned char it8172_rtc_read_data(unsigned long addr)
-{
-       unsigned char retval;
-
-       *rtc_adr_reg = addr;
-       retval =  *rtc_dat_reg;
-       return retval;
-}
-
-void it8172_rtc_write_data(unsigned char data, unsigned long addr)
-{
-       *rtc_adr_reg = addr;
-       *rtc_dat_reg = data;
-}
-
-#undef         CMOS_READ
-#undef         CMOS_WRITE
-#define        CMOS_READ(addr)                 it8172_rtc_read_data(addr)
-#define CMOS_WRITE(data, addr)                 it8172_rtc_write_data(data, addr)
-
-static unsigned char saved_control;    /* remember rtc control reg */
-static inline int rtc_24h(void) { return saved_control & RTC_24H; }
-static inline int rtc_dm_binary(void) { return saved_control & RTC_DM_BINARY; }
-
-static inline unsigned char
-bin_to_hw(unsigned char c)
-{
-       if (rtc_dm_binary())
-               return c;
-       else
-               return ((c/10) << 4) + (c%10);
-}
-
-static inline unsigned char
-hw_to_bin(unsigned char c)
-{
-       if (rtc_dm_binary())
-               return c;
-       else
-               return (c>>4)*10 + (c &0xf);
-}
-
-/* 0x80 bit indicates pm in 12-hour format */
-static inline unsigned char
-hour_bin_to_hw(unsigned char c)
-{
-       if (rtc_24h())
-               return bin_to_hw(c);
-       if (c >= 12)
-               return 0x80 | bin_to_hw((c==12)?12:c-12);  /* 12 is 12pm */
-       else
-               return bin_to_hw((c==0)?12:c);  /* 0 is 12 AM, not 0 am */
-}
-
-static inline unsigned char
-hour_hw_to_bin(unsigned char c)
-{
-       unsigned char tmp = hw_to_bin(c&0x3f);
-       if (rtc_24h())
-               return tmp;
-       if (c & 0x80)
-               return (tmp==12)?12:tmp+12;     /* 12pm is 12, not 24 */
-       else
-               return (tmp==12)?0:tmp;         /* 12am is 0 */
-}
-
-static unsigned long r4k_offset; /* Amount to increment compare reg each time */
-static unsigned long r4k_cur;    /* What counter should be at next timer irq */
-extern unsigned int mips_hpt_frequency;
-
-/*
- * Figure out the r4k offset, the amount to increment the compare
- * register for each time tick.
- * Use the RTC to calculate offset.
- */
-static unsigned long __init cal_r4koff(void)
-{
-       unsigned int flags;
-
-       local_irq_save(flags);
-
-       /* Start counter exactly on falling edge of update flag */
-       while (CMOS_READ(RTC_REG_A) & RTC_UIP);
-       while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
-
-       /* Start r4k counter. */
-       write_c0_count(0);
-
-       /* Read counter exactly on falling edge of update flag */
-       while (CMOS_READ(RTC_REG_A) & RTC_UIP);
-       while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
-
-       mips_hpt_frequency = read_c0_count();
-
-       /* restore interrupts */
-       local_irq_restore(flags);
-
-       return (mips_hpt_frequency / HZ);
-}
-
-static unsigned long
-it8172_rtc_get_time(void)
-{
-       unsigned int year, mon, day, hour, min, sec;
-       unsigned int flags;
-
-       /* avoid update-in-progress. */
-       for (;;) {
-               local_irq_save(flags);
-               if (! (CMOS_READ(RTC_REG_A) & RTC_UIP))
-                       break;
-               /* don't hold intr closed all the time */
-               local_irq_restore(flags);
-       }
-
-       /* Read regs. */
-       sec = hw_to_bin(CMOS_READ(RTC_SECONDS));
-       min = hw_to_bin(CMOS_READ(RTC_MINUTES));
-       hour = hour_hw_to_bin(CMOS_READ(RTC_HOURS));
-       day = hw_to_bin(CMOS_READ(RTC_DAY_OF_MONTH));
-       mon = hw_to_bin(CMOS_READ(RTC_MONTH));
-       year = hw_to_bin(CMOS_READ(RTC_YEAR)) +
-               hw_to_bin(*rtc_century_reg) * 100;
-
-       /* restore interrupts */
-       local_irq_restore(flags);
-
-       return mktime(year, mon, day, hour, min, sec);
-}
-
-static int
-it8172_rtc_set_time(unsigned long t)
-{
-       struct rtc_time tm;
-       unsigned int flags;
-
-       /* convert */
-       to_tm(t, &tm);
-
-       /* avoid update-in-progress. */
-       for (;;) {
-               local_irq_save(flags);
-               if (! (CMOS_READ(RTC_REG_A) & RTC_UIP))
-                       break;
-               /* don't hold intr closed all the time */
-               local_irq_restore(flags);
-       }
-
-       *rtc_century_reg = bin_to_hw(tm.tm_year/100);
-       CMOS_WRITE(bin_to_hw(tm.tm_sec), RTC_SECONDS);
-       CMOS_WRITE(bin_to_hw(tm.tm_min), RTC_MINUTES);
-       CMOS_WRITE(hour_bin_to_hw(tm.tm_hour), RTC_HOURS);
-       CMOS_WRITE(bin_to_hw(tm.tm_mday), RTC_DAY_OF_MONTH);
-       CMOS_WRITE(bin_to_hw(tm.tm_mon+1), RTC_MONTH);  /* tm_mon starts from 0 */
-       CMOS_WRITE(bin_to_hw(tm.tm_year%100), RTC_YEAR);
-
-       /* restore interrupts */
-       local_irq_restore(flags);
-
-       return 0;
-}
-
-void __init it8172_time_init(void)
-{
-        unsigned int est_freq, flags;
-
-       local_irq_save(flags);
-
-       saved_control = CMOS_READ(RTC_CONTROL);
-
-       printk("calculating r4koff... ");
-       r4k_offset = cal_r4koff();
-       printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);
-
-       est_freq = 2*r4k_offset*HZ;
-       est_freq += 5000;    /* round */
-       est_freq -= est_freq%10000;
-       printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
-              (est_freq%1000000)*100/1000000);
-
-       local_irq_restore(flags);
-
-       rtc_mips_get_time = it8172_rtc_get_time;
-       rtc_mips_set_time = it8172_rtc_set_time;
-}
-
-#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
-
-void __init plat_timer_setup(struct irqaction *irq)
-{
-       puts("timer_setup\n");
-       put32(NR_IRQS);
-       puts("");
-        /* we are using the cpu counter for timer interrupts */
-       setup_irq(MIPS_CPU_TIMER_IRQ, irq);
-
-        /* to generate the first timer interrupt */
-       r4k_cur = (read_c0_count() + r4k_offset);
-       write_c0_compare(r4k_cur);
-       set_c0_status(ALLINTS);
-}
diff --git a/arch/mips/ite-boards/ivr/Makefile b/arch/mips/ite-boards/ivr/Makefile
deleted file mode 100644 (file)
index e4fa604..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-#  Copyright 2000 MontaVista Software Inc.
-#  Author: MontaVista Software, Inc.
-#      ppopov@mvista.com or source@mvista.com
-#
-# Makefile for the Globespan IVR board,
-# board-specific files.
-#
-
-obj-y          += init.o
diff --git a/arch/mips/ite-boards/ivr/README b/arch/mips/ite-boards/ivr/README
deleted file mode 100644 (file)
index aa7d8db..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-This is not really a board made by ITE Semi, but it's very
-similar to the ITE QED-4N-S01B board.  The IVR board is made
-by Globespan and it's a reference board for the PVR chip.
diff --git a/arch/mips/ite-boards/ivr/init.c b/arch/mips/ite-boards/ivr/init.c
deleted file mode 100644 (file)
index 05cf921..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- *     IVR board setup.
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@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.
- */
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/bootmem.h>
-#include <asm/addrspace.h>
-#include <asm/bootinfo.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <asm/sections.h>
-#include <asm/it8172/it8172.h>
-#include <asm/it8172/it8172_dbg.h>
-
-int prom_argc;
-char **prom_argv, **prom_envp;
-
-extern void  __init prom_init_cmdline(void);
-extern unsigned long __init prom_get_memsize(void);
-extern void __init it8172_init_ram_resource(unsigned long memsize);
-
-const char *get_system_type(void)
-{
-       return "Globespan IVR";
-}
-
-void __init prom_init(void)
-{
-       unsigned long mem_size;
-       unsigned long pcicr;
-
-       prom_argc = fw_arg0;
-       prom_argv = (char **) fw_arg1;
-       prom_envp = (int *) fw_arg3;
-
-       mips_machgroup = MACH_GROUP_GLOBESPAN;
-       mips_machtype = MACH_IVR;  /* Globespan's iTVC15 reference board */
-
-       prom_init_cmdline();
-
-       /* pmon does not set memsize */
-       mem_size = prom_get_memsize();
-       mem_size = mem_size << 20;
-
-       /*
-        * make the entire physical memory visible to pci bus masters
-        */
-       IT_READ(IT_MC_PCICR, pcicr);
-       pcicr &= ~0x1f;
-       pcicr |= (mem_size - 1) >> 22;
-       IT_WRITE(IT_MC_PCICR, pcicr);
-
-       it8172_init_ram_resource(mem_size);
-       add_memory_region(0, mem_size, BOOT_MEM_RAM);
-}
diff --git a/arch/mips/ite-boards/qed-4n-s01b/Makefile b/arch/mips/ite-boards/qed-4n-s01b/Makefile
deleted file mode 100644 (file)
index bb9972a..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-#  Copyright 2000 MontaVista Software Inc.
-#  Author: MontaVista Software, Inc.
-#      ppopov@mvista.com or source@mvista.com
-#
-# Makefile for the ITE 8172 (qed-4n-s01b) board, board
-# specific files.
-#
-
-obj-y := init.o
diff --git a/arch/mips/ite-boards/qed-4n-s01b/README b/arch/mips/ite-boards/qed-4n-s01b/README
deleted file mode 100644 (file)
index fb4b519..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-This is an ITE (www.iteusa.com) eval board for the ITE 8172G
-system controller, with a QED 5231 CPU.
diff --git a/arch/mips/ite-boards/qed-4n-s01b/init.c b/arch/mips/ite-boards/qed-4n-s01b/init.c
deleted file mode 100644 (file)
index ea2a754..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- *     IT8172/QED5231 board setup.
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@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.
- */
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/bootmem.h>
-#include <asm/addrspace.h>
-#include <asm/bootinfo.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <asm/sections.h>
-#include <asm/it8172/it8172.h>
-#include <asm/it8172/it8172_dbg.h>
-
-int prom_argc;
-char **prom_argv, **prom_envp;
-
-extern void  __init prom_init_cmdline(void);
-extern unsigned long __init prom_get_memsize(void);
-extern void __init it8172_init_ram_resource(unsigned long memsize);
-
-const char *get_system_type(void)
-{
-       return "ITE QED-4N-S01B";
-}
-
-void __init prom_init(void)
-{
-       unsigned long mem_size;
-       unsigned long pcicr;
-
-       prom_argc = fw_arg0;
-       prom_argv = (char **) fw_arg1;
-       prom_envp = (int *) fw_arg3;
-
-       mips_machgroup = MACH_GROUP_ITE;
-       mips_machtype = MACH_QED_4N_S01B;  /* ITE board name/number */
-
-       prom_init_cmdline();
-       mem_size = prom_get_memsize();
-
-       printk("Memory size: %dMB\n", (unsigned)mem_size);
-
-       mem_size <<= 20; /* MB */
-
-       /*
-        * make the entire physical memory visible to pci bus masters
-        */
-       IT_READ(IT_MC_PCICR, pcicr);
-       pcicr &= ~0x1f;
-       pcicr |= (mem_size - 1) >> 22;
-       IT_WRITE(IT_MC_PCICR, pcicr);
-
-       it8172_init_ram_resource(mem_size);
-       add_memory_region(0, mem_size, BOOT_MEM_RAM);
-}
index 881c467c698241d2902454b603de9b4e4dae4ae7..cd9cec9e39e931c85c3f8af50e562615e281bf93 100644 (file)
@@ -11,6 +11,7 @@ obj-y         += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
 binfmt_irix-objs       := irixelf.o irixinv.o irixioctl.o irixsig.o    \
                           irix5sys.o sysirix.o
 
+obj-$(CONFIG_STACKTRACE)       += stacktrace.o
 obj-$(CONFIG_MODULES)          += mips_ksyms.o module.o
 
 obj-$(CONFIG_APM)              += apm.o
index 37fda3dcdfc5b84bdbd57c785187ec3086b50ade..af6ef2fd8300338f26e45e3acf7073027b8a6df6 100644 (file)
@@ -220,8 +220,8 @@ NESTED(except_vec_vi_handler, 0, sp)
        CLI
        TRACE_IRQS_OFF
        move    a0, sp
-       jalr    v0
-       j       ret_from_irq
+       PTR_LA  ra, ret_from_irq
+       jr      v0
        END(except_vec_vi_handler)
 
 /*
@@ -349,8 +349,8 @@ NESTED(nmi_handler, PT_SIZE, sp)
        .set    at
        __BUILD_\verbose \exception
        move    a0, sp
-       jal     do_\handler
-       j       ret_from_exception
+       PTR_LA  ra, ret_from_exception
+       j       do_\handler
        END(handle_\exception)
        .endm
 
index ea36c8e8852c1b9f1b0c2c5e789e5d6e4e40ee29..48e3418c217b8445509fa6326daf2fefbfc2a220 100644 (file)
@@ -302,11 +302,11 @@ static struct irqaction irq2 = {
 };
 
 static struct resource pic1_io_resource = {
-       .name = "pic1", .start = 0x20, .end = 0x3f, .flags = IORESOURCE_BUSY
+       .name = "pic1", .start = 0x20, .end = 0x21, .flags = IORESOURCE_BUSY
 };
 
 static struct resource pic2_io_resource = {
-       .name = "pic2", .start = 0xa0, .end = 0xbf, .flags = IORESOURCE_BUSY
+       .name = "pic2", .start = 0xa0, .end = 0xa1, .flags = IORESOURCE_BUSY
 };
 
 /*
index 43b1162d714f281db07a3bad5b53bcf0576f8423..53f4171fc188a9695eb094b6a4ddda7977af349c 100644 (file)
@@ -77,6 +77,8 @@ int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
        memset(&tmp, 0, sizeof(tmp));
        tmp.st_dev = new_encode_dev(stat->dev);
        tmp.st_ino = stat->ino;
+       if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
+               return -EOVERFLOW;
        tmp.st_mode = stat->mode;
        tmp.st_nlink = stat->nlink;
        SET_UID(tmp.st_uid, stat->uid);
@@ -1039,7 +1041,7 @@ asmlinkage long sys32_newuname(struct new_utsname __user * name)
        int ret = 0;
 
        down_read(&uts_sem);
-       if (copy_to_user(name,&system_utsname,sizeof *name))
+       if (copy_to_user(name, utsname(), sizeof *name))
                ret = -EFAULT;
        up_read(&uts_sem);
 
index 2613a0dd4b823bde6959cd575d194cb8cb5677b8..045d987bc683b3da05fe6f5a700c413154d9e5f8 100644 (file)
@@ -40,6 +40,7 @@
 #include <asm/elf.h>
 #include <asm/isadep.h>
 #include <asm/inst.h>
+#include <asm/stacktrace.h>
 #ifdef CONFIG_MIPS_MT_SMTC
 #include <asm/mipsmtregs.h>
 extern void smtc_idle_loop_hook(void);
@@ -398,7 +399,7 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
 #ifdef CONFIG_KALLSYMS
 /* used by show_backtrace() */
 unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
-                          unsigned long pc, unsigned long ra)
+                          unsigned long pc, unsigned long *ra)
 {
        unsigned long stack_page;
        struct mips_frame_info info;
@@ -406,18 +407,42 @@ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
        char namebuf[KSYM_NAME_LEN + 1];
        unsigned long size, ofs;
        int leaf;
+       extern void ret_from_irq(void);
+       extern void ret_from_exception(void);
 
        stack_page = (unsigned long)task_stack_page(task);
        if (!stack_page)
                return 0;
 
+       /*
+        * If we reached the bottom of interrupt context,
+        * return saved pc in pt_regs.
+        */
+       if (pc == (unsigned long)ret_from_irq ||
+           pc == (unsigned long)ret_from_exception) {
+               struct pt_regs *regs;
+               if (*sp >= stack_page &&
+                   *sp + sizeof(*regs) <= stack_page + THREAD_SIZE - 32) {
+                       regs = (struct pt_regs *)*sp;
+                       pc = regs->cp0_epc;
+                       if (__kernel_text_address(pc)) {
+                               *sp = regs->regs[29];
+                               *ra = regs->regs[31];
+                               return pc;
+                       }
+               }
+               return 0;
+       }
        if (!kallsyms_lookup(pc, &size, &ofs, &modname, namebuf))
                return 0;
        /*
         * Return ra if an exception occured at the first instruction
         */
-       if (unlikely(ofs == 0))
-               return ra;
+       if (unlikely(ofs == 0)) {
+               pc = *ra;
+               *ra = 0;
+               return pc;
+       }
 
        info.func = (void *)(pc - ofs);
        info.func_size = ofs;   /* analyze from start to ofs */
@@ -436,11 +461,12 @@ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
                 * one. In that cases avoid to return always the
                 * same value.
                 */
-               pc = pc != ra ? ra : 0;
+               pc = pc != *ra ? *ra : 0;
        else
                pc = ((unsigned long *)(*sp))[info.pc_offset];
 
        *sp += info.frame_size;
+       *ra = 0;
        return __kernel_text_address(pc) ? pc : 0;
 }
 #endif
@@ -453,6 +479,7 @@ unsigned long get_wchan(struct task_struct *task)
        unsigned long pc = 0;
 #ifdef CONFIG_KALLSYMS
        unsigned long sp;
+       unsigned long ra = 0;
 #endif
 
        if (!task || task == current || task->state == TASK_RUNNING)
@@ -466,7 +493,7 @@ unsigned long get_wchan(struct task_struct *task)
        sp = task->thread.reg29 + schedule_mfi.frame_size;
 
        while (in_sched_functions(pc))
-               pc = unwind_stack(task, &sp, pc, 0);
+               pc = unwind_stack(task, &sp, pc, &ra);
 #endif
 
 out:
index e7178510220635c5da2be58e59c3b839a36a0bfa..61362e6fa9eccfbfb79b8abfde01d57b431f6e08 100644 (file)
 NESTED(handle_sys, PT_SIZE, sp)
        .set    noat
        SAVE_SOME
-#ifdef CONFIG_TRACE_IRQFLAGS
-       TRACE_IRQS_ON
-#ifdef CONFIG_64BIT
-       LONG_L  $8, PT_R8(sp)
-       LONG_L  $9, PT_R9(sp)
-#endif
-       LONG_L  $7, PT_R7(sp)
-       LONG_L  $6, PT_R6(sp)
-       LONG_L  $5, PT_R5(sp)
-       LONG_L  $4, PT_R4(sp)
-       LONG_L  $2, PT_R2(sp)
-#endif
+       TRACE_IRQS_ON_RELOAD
        STI
        .set    at
 
index 4c22d0b4825dc70bcdfb5d239dc458d60d6c185c..6c7b5ed0ea6e0ccec04ebfff052e0e9fd2fc780e 100644 (file)
@@ -34,7 +34,7 @@ NESTED(handle_sys64, PT_SIZE, sp)
         */
        .set    noat
        SAVE_SOME
-       TRACE_IRQS_ON
+       TRACE_IRQS_ON_RELOAD
        STI
        .set    at
 #endif
index f25c2a2f10387b10128bd92251cc9ee8df45559f..6d9f18727ac51e5baf3232f4624f733c8789732b 100644 (file)
@@ -33,7 +33,7 @@ NESTED(handle_sysn32, PT_SIZE, sp)
 #ifndef CONFIG_MIPS32_O32
        .set    noat
        SAVE_SOME
-       TRACE_IRQS_ON
+       TRACE_IRQS_ON_RELOAD
        STI
        .set    at
 #endif
index 288ee4ac4dbb8cce221c6b530b3da04bdae4eea1..2e6d0673163e1896cc2ac05d3299755f77f43aac 100644 (file)
@@ -28,7 +28,7 @@
 NESTED(handle_sys, PT_SIZE, sp)
        .set    noat
        SAVE_SOME
-       TRACE_IRQS_ON
+       TRACE_IRQS_ON_RELOAD
        STI
        .set    at
        ld      t1, PT_EPC(sp)          # skip syscall on return
index 50c17eaa7f252c0012efb15054c25797a793cea4..477c5334ec1b459eefb010c9ef5918ca1358b47b 100644 (file)
@@ -42,8 +42,6 @@
 
 #include "signal-common.h"
 
-extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
-
 /*
  * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
  */
@@ -83,6 +81,8 @@ struct rt_sigframe_n32 {
 #endif
 };
 
+extern void sigset_from_compat (sigset_t *set, compat_sigset_t *compat);
+
 save_static_function(sysn32_rt_sigsuspend);
 __attribute_used__ noinline static int
 _sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
diff --git a/arch/mips/kernel/stacktrace.c b/arch/mips/kernel/stacktrace.c
new file mode 100644 (file)
index 0000000..4aabe52
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * arch/mips/kernel/stacktrace.c
+ *
+ * Stack trace management functions
+ *
+ *  Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
+ */
+#include <linux/sched.h>
+#include <linux/stacktrace.h>
+#include <asm/stacktrace.h>
+
+/*
+ * Save stack-backtrace addresses into a stack_trace buffer:
+ */
+static void save_raw_context_stack(struct stack_trace *trace,
+       unsigned long reg29)
+{
+       unsigned long *sp = (unsigned long *)reg29;
+       unsigned long addr;
+
+       while (!kstack_end(sp)) {
+               addr = *sp++;
+               if (__kernel_text_address(addr)) {
+                       if (trace->skip > 0)
+                               trace->skip--;
+                       else
+                               trace->entries[trace->nr_entries++] = addr;
+                       if (trace->nr_entries >= trace->max_entries)
+                               break;
+               }
+       }
+}
+
+static void save_context_stack(struct stack_trace *trace,
+       struct task_struct *task, struct pt_regs *regs)
+{
+       unsigned long sp = regs->regs[29];
+#ifdef CONFIG_KALLSYMS
+       unsigned long ra = regs->regs[31];
+       unsigned long pc = regs->cp0_epc;
+
+       if (raw_show_trace || !__kernel_text_address(pc)) {
+               unsigned long stack_page =
+                       (unsigned long)task_stack_page(task);
+               if (stack_page && sp >= stack_page &&
+                   sp <= stack_page + THREAD_SIZE - 32)
+                       save_raw_context_stack(trace, sp);
+               return;
+       }
+       do {
+               if (trace->skip > 0)
+                       trace->skip--;
+               else
+                       trace->entries[trace->nr_entries++] = pc;
+               if (trace->nr_entries >= trace->max_entries)
+                       break;
+               pc = unwind_stack(task, &sp, pc, &ra);
+       } while (pc);
+#else
+       save_raw_context_stack(sp);
+#endif
+}
+
+/*
+ * Save stack-backtrace addresses into a stack_trace buffer.
+ */
+void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
+{
+       struct pt_regs dummyregs;
+       struct pt_regs *regs = &dummyregs;
+
+       WARN_ON(trace->nr_entries || !trace->max_entries);
+
+       if (task && task != current) {
+               regs->regs[29] = task->thread.reg29;
+               regs->regs[31] = 0;
+               regs->cp0_epc = task->thread.reg31;
+       } else {
+               if (!task)
+                       task = current;
+               prepare_frametrace(regs);
+       }
+
+       save_context_stack(trace, task, regs);
+}
index 9951240cc3fd23fde7c356542534de4c79a904af..26e1a7e78d13dac0acac8277572c88c74c9a106a 100644 (file)
@@ -231,7 +231,7 @@ out:
  */
 asmlinkage int sys_uname(struct old_utsname __user * name)
 {
-       if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
+       if (name && !copy_to_user(name, utsname(), sizeof (*name)))
                return 0;
        return -EFAULT;
 }
@@ -248,16 +248,21 @@ asmlinkage int sys_olduname(struct oldold_utsname __user * name)
        if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
                return -EFAULT;
 
-       error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
-       error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
-       error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
-       error -= __put_user(0,name->nodename+__OLD_UTS_LEN);
-       error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
-       error -= __put_user(0,name->release+__OLD_UTS_LEN);
-       error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
-       error -= __put_user(0,name->version+__OLD_UTS_LEN);
-       error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
-       error = __put_user(0,name->machine+__OLD_UTS_LEN);
+       error = __copy_to_user(&name->sysname, &utsname()->sysname,
+                              __OLD_UTS_LEN);
+       error -= __put_user(0, name->sysname + __OLD_UTS_LEN);
+       error -= __copy_to_user(&name->nodename, &utsname()->nodename,
+                               __OLD_UTS_LEN);
+       error -= __put_user(0, name->nodename + __OLD_UTS_LEN);
+       error -= __copy_to_user(&name->release, &utsname()->release,
+                               __OLD_UTS_LEN);
+       error -= __put_user(0, name->release + __OLD_UTS_LEN);
+       error -= __copy_to_user(&name->version, &utsname()->version,
+                               __OLD_UTS_LEN);
+       error -= __put_user(0, name->version + __OLD_UTS_LEN);
+       error -= __copy_to_user(&name->machine, &utsname()->machine,
+                               __OLD_UTS_LEN);
+       error = __put_user(0, name->machine + __OLD_UTS_LEN);
        error = error ? -EFAULT : 0;
 
        return error;
@@ -401,3 +406,32 @@ asmlinkage void bad_stack(void)
 {
        do_exit(SIGSEGV);
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+       register unsigned long __a0 asm("$4") = (unsigned long) filename;
+       register unsigned long __a1 asm("$5") = (unsigned long) argv;
+       register unsigned long __a2 asm("$6") = (unsigned long) envp;
+       register unsigned long __a3 asm("$7");
+       unsigned long __v0;
+
+       __asm__ volatile ("                                     \n"
+       "       .set    noreorder                               \n"
+       "       li      $2, %5          # __NR_execve           \n"
+       "       syscall                                         \n"
+       "       move    %0, $2                                  \n"
+       "       .set    reorder                                 \n"
+       : "=&r" (__v0), "=r" (__a3)
+       : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_execve)
+       : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24",
+         "memory");
+
+       if (__a3 == 0)
+               return __v0;
+
+       return -__v0;
+}
index 1137dd6ea7aa914bd91c3ec10722c843ef531ebe..93c74fefff766e9c3cc035a57011a3e62d992a1a 100644 (file)
@@ -884,7 +884,7 @@ asmlinkage int irix_getdomainname(char __user *name, int len)
        down_read(&uts_sem);
        if (len > __NEW_UTS_LEN)
                len = __NEW_UTS_LEN;
-       err = copy_to_user(name, system_utsname.domainname, len) ? -EFAULT : 0;
+       err = copy_to_user(name, utsname()->domainname, len) ? -EFAULT : 0;
        up_read(&uts_sem);
 
        return err;
@@ -1127,11 +1127,11 @@ struct iuname {
 asmlinkage int irix_uname(struct iuname __user *buf)
 {
        down_read(&uts_sem);
-       if (copy_from_user(system_utsname.sysname, buf->sysname, 65)
-           || copy_from_user(system_utsname.nodename, buf->nodename, 65)
-           || copy_from_user(system_utsname.release, buf->release, 65)
-           || copy_from_user(system_utsname.version, buf->version, 65)
-           || copy_from_user(system_utsname.machine, buf->machine, 65)) {
+       if (copy_from_user(utsname()->sysname, buf->sysname, 65)
+           || copy_from_user(utsname()->nodename, buf->nodename, 65)
+           || copy_from_user(utsname()->release, buf->release, 65)
+           || copy_from_user(utsname()->version, buf->version, 65)
+           || copy_from_user(utsname()->machine, buf->machine, 65)) {
                return -EFAULT;
        }
        up_read(&uts_sem);
@@ -1739,12 +1739,13 @@ struct irix_dirent32_callback {
 #define ROUND_UP32(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
 
 static int irix_filldir32(void *__buf, const char *name,
-       int namlen, loff_t offset, ino_t ino, unsigned int d_type)
+       int namlen, loff_t offset, u64 ino, unsigned int d_type)
 {
        struct irix_dirent32 __user *dirent;
        struct irix_dirent32_callback *buf = __buf;
        unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1);
        int err = 0;
+       u32 d_ino;
 
 #ifdef DEBUG_GETDENTS
        printk("\nirix_filldir32[reclen<%d>namlen<%d>count<%d>]",
@@ -1753,12 +1754,15 @@ static int irix_filldir32(void *__buf, const char *name,
        buf->error = -EINVAL;   /* only used if we fail.. */
        if (reclen > buf->count)
                return -EINVAL;
+       d_ino = ino;
+       if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+               return -EOVERFLOW;
        dirent = buf->previous;
        if (dirent)
                err = __put_user(offset, &dirent->d_off);
        dirent = buf->current_dir;
        err |= __put_user(dirent, &buf->previous);
-       err |= __put_user(ino, &dirent->d_ino);
+       err |= __put_user(d_ino, &dirent->d_ino);
        err |= __put_user(reclen, &dirent->d_reclen);
        err |= copy_to_user((char __user *)dirent->d_name, name, namlen) ? -EFAULT : 0;
        err |= __put_user(0, &dirent->d_name[namlen]);
@@ -1837,7 +1841,7 @@ struct irix_dirent64_callback {
 #define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))
 
 static int irix_filldir64(void *__buf, const char *name,
-       int namlen, loff_t offset, ino_t ino, unsigned int d_type)
+       int namlen, loff_t offset, u64 ino, unsigned int d_type)
 {
        struct irix_dirent64 __user *dirent;
        struct irix_dirent64_callback * buf = __buf;
index 845c7e55505d39f3335e66f031e723b2729d6406..a8340802f2d76a3c27acd634a1e658b6a0a8518e 100644 (file)
@@ -149,80 +149,6 @@ void (*mips_timer_ack)(void);
 unsigned int (*mips_hpt_read)(void);
 void (*mips_hpt_init)(unsigned int);
 
-
-/*
- * This version of gettimeofday has microsecond resolution and better than
- * microsecond precision on fast machines with cycle counter.
- */
-void do_gettimeofday(struct timeval *tv)
-{
-       unsigned long seq;
-       unsigned long usec, sec;
-       unsigned long max_ntp_tick;
-
-       do {
-               seq = read_seqbegin(&xtime_lock);
-
-               usec = do_gettimeoffset();
-
-               /*
-                * If time_adjust is negative then NTP is slowing the clock
-                * so make sure not to go into next possible interval.
-                * Better to lose some accuracy than have time go backwards..
-                */
-               if (unlikely(time_adjust < 0)) {
-                       max_ntp_tick = (USEC_PER_SEC / HZ) - tickadj;
-                       usec = min(usec, max_ntp_tick);
-               }
-
-               sec = xtime.tv_sec;
-               usec += (xtime.tv_nsec / 1000);
-
-       } while (read_seqretry(&xtime_lock, seq));
-
-       while (usec >= 1000000) {
-               usec -= 1000000;
-               sec++;
-       }
-
-       tv->tv_sec = sec;
-       tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
-{
-       time_t wtm_sec, sec = tv->tv_sec;
-       long wtm_nsec, nsec = tv->tv_nsec;
-
-       if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
-               return -EINVAL;
-
-       write_seqlock_irq(&xtime_lock);
-
-       /*
-        * This is revolting.  We need to set "xtime" correctly.  However,
-        * the value in this location is the value at the most recent update
-        * of wall time.  Discover what correction gettimeofday() would have
-        * made, and then undo it!
-        */
-       nsec -= do_gettimeoffset() * NSEC_PER_USEC;
-
-       wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
-       wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
-       set_normalized_timespec(&xtime, sec, nsec);
-       set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
-       ntp_clear();
-       write_sequnlock_irq(&xtime_lock);
-       clock_was_set();
-       return 0;
-}
-
-EXPORT_SYMBOL(do_settimeofday);
-
 /*
  * Gettimeoffset routines.  These routines returns the time duration
  * since last timer interrupt in usecs.
index e51d8fd9a15234ec4d3e5fabcafb22b24010f6ed..b7292a56d4cd80b65d4bf2ef6f6ff016d371c857 100644 (file)
@@ -41,6 +41,7 @@
 #include <asm/mmu_context.h>
 #include <asm/watch.h>
 #include <asm/types.h>
+#include <asm/stacktrace.h>
 
 extern asmlinkage void handle_int(void);
 extern asmlinkage void handle_tlbm(void);
@@ -92,16 +93,14 @@ static void show_raw_backtrace(unsigned long reg29)
 }
 
 #ifdef CONFIG_KALLSYMS
-static int raw_show_trace;
+int raw_show_trace;
 static int __init set_raw_show_trace(char *str)
 {
        raw_show_trace = 1;
        return 1;
 }
 __setup("raw_show_trace", set_raw_show_trace);
-
-extern unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
-                                 unsigned long pc, unsigned long ra);
+#endif
 
 static void show_backtrace(struct task_struct *task, struct pt_regs *regs)
 {
@@ -116,14 +115,10 @@ static void show_backtrace(struct task_struct *task, struct pt_regs *regs)
        printk("Call Trace:\n");
        do {
                print_ip_sym(pc);
-               pc = unwind_stack(task, &sp, pc, ra);
-               ra = 0;
+               pc = unwind_stack(task, &sp, pc, &ra);
        } while (pc);
        printk("\n");
 }
-#else
-#define show_backtrace(task, r) show_raw_backtrace((r)->regs[29]);
-#endif
 
 /*
  * This routine abuses get_user()/put_user() to reference pointers
@@ -158,28 +153,6 @@ static void show_stacktrace(struct task_struct *task, struct pt_regs *regs)
        show_backtrace(task, regs);
 }
 
-static __always_inline void prepare_frametrace(struct pt_regs *regs)
-{
-       __asm__ __volatile__(
-               ".set push\n\t"
-               ".set noat\n\t"
-#ifdef CONFIG_64BIT
-               "1: dla $1, 1b\n\t"
-               "sd $1, %0\n\t"
-               "sd $29, %1\n\t"
-               "sd $31, %2\n\t"
-#else
-               "1: la $1, 1b\n\t"
-               "sw $1, %0\n\t"
-               "sw $29, %1\n\t"
-               "sw $31, %2\n\t"
-#endif
-               ".set pop\n\t"
-               : "=m" (regs->cp0_epc),
-               "=m" (regs->regs[29]), "=m" (regs->regs[31])
-               : : "memory");
-}
-
 void show_stack(struct task_struct *task, unsigned long *sp)
 {
        struct pt_regs regs;
@@ -206,11 +179,6 @@ void dump_stack(void)
 {
        struct pt_regs regs;
 
-       /*
-        * Remove any garbage that may be in regs (specially func
-        * addresses) to avoid show_raw_backtrace() to report them
-        */
-       memset(&regs, 0, sizeof(regs));
        prepare_frametrace(&regs);
        show_backtrace(current, &regs);
 }
index 0ffc43c600d9a39ef3d7a55cf8ac60244458884e..14c55168f1ff11d50016fa0afe25feea24443f73 100644 (file)
@@ -34,7 +34,6 @@
 #include <asm/cpu.h>
 #include <asm/bootinfo.h>
 #include <asm/irq.h>
-#include <asm/serial.h>
 #include <asm/lasat/lasat.h>
 #include <asm/lasat/serial.h>
 
index e1f35ef81145445c5530ccbdca83b4715a040c2d..d1af42c2a52e1b24c4342ab1a2990ededac007e6 100644 (file)
@@ -268,26 +268,6 @@ static void r3k_flush_data_cache_page(unsigned long addr)
 {
 }
 
-static void r3k_flush_icache_page(struct vm_area_struct *vma, struct page *page)
-{
-       struct mm_struct *mm = vma->vm_mm;
-       unsigned long physpage;
-
-       if (cpu_context(smp_processor_id(), mm) == 0)
-               return;
-
-       if (!(vma->vm_flags & VM_EXEC))
-               return;
-
-#ifdef DEBUG_CACHE
-       printk("cpage[%d,%08lx]", cpu_context(smp_processor_id(), mm), page);
-#endif
-
-       physpage = (unsigned long) page_address(page);
-       if (physpage)
-               r3k_flush_icache_range(physpage, physpage + PAGE_SIZE);
-}
-
 static void r3k_flush_cache_sigtramp(unsigned long addr)
 {
        unsigned long flags;
@@ -335,7 +315,6 @@ void __init r3k_cache_init(void)
        flush_cache_mm = r3k_flush_cache_mm;
        flush_cache_range = r3k_flush_cache_range;
        flush_cache_page = r3k_flush_cache_page;
-       __flush_icache_page = r3k_flush_icache_page;
        flush_icache_range = r3k_flush_icache_range;
 
        flush_cache_sigtramp = r3k_flush_cache_sigtramp;
index 0b2da53750bd4220a30d1e97d7016d436a41ce6e..cc895dad71d2297094243bd5d23d8d411d4893c0 100644 (file)
@@ -551,82 +551,6 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end)
        instruction_hazard();
 }
 
-/*
- * Ok, this seriously sucks.  We use them to flush a user page but don't
- * know the virtual address, so we have to blast away the whole icache
- * which is significantly more expensive than the real thing.  Otoh we at
- * least know the kernel address of the page so we can flush it
- * selectivly.
- */
-
-struct flush_icache_page_args {
-       struct vm_area_struct *vma;
-       struct page *page;
-};
-
-static inline void local_r4k_flush_icache_page(void *args)
-{
-       struct flush_icache_page_args *fip_args = args;
-       struct vm_area_struct *vma = fip_args->vma;
-       struct page *page = fip_args->page;
-
-       /*
-        * Tricky ...  Because we don't know the virtual address we've got the
-        * choice of either invalidating the entire primary and secondary
-        * caches or invalidating the secondary caches also.  With the subset
-        * enforcment on R4000SC, R4400SC, R10000 and R12000 invalidating the
-        * secondary cache will result in any entries in the primary caches
-        * also getting invalidated which hopefully is a bit more economical.
-        */
-       if (cpu_has_inclusive_pcaches) {
-               unsigned long addr = (unsigned long) page_address(page);
-
-               r4k_blast_scache_page(addr);
-               ClearPageDcacheDirty(page);
-
-               return;
-       }
-
-       if (!cpu_has_ic_fills_f_dc) {
-               unsigned long addr = (unsigned long) page_address(page);
-               r4k_blast_dcache_page(addr);
-               if (!cpu_icache_snoops_remote_store)
-                       r4k_blast_scache_page(addr);
-               ClearPageDcacheDirty(page);
-       }
-
-       /*
-        * We're not sure of the virtual address(es) involved here, so
-        * we have to flush the entire I-cache.
-        */
-       if (cpu_has_vtag_icache && vma->vm_mm == current->active_mm) {
-               int cpu = smp_processor_id();
-
-               if (cpu_context(cpu, vma->vm_mm) != 0)
-                       drop_mmu_context(vma->vm_mm, cpu);
-       } else
-               r4k_blast_icache();
-}
-
-static void r4k_flush_icache_page(struct vm_area_struct *vma,
-       struct page *page)
-{
-       struct flush_icache_page_args args;
-
-       /*
-        * If there's no context yet, or the page isn't executable, no I-cache
-        * flush is needed.
-        */
-       if (!(vma->vm_flags & VM_EXEC))
-               return;
-
-       args.vma = vma;
-       args.page = page;
-
-       r4k_on_each_cpu(local_r4k_flush_icache_page, &args, 1, 1);
-}
-
-
 #ifdef CONFIG_DMA_NONCOHERENT
 
 static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
@@ -1291,7 +1215,6 @@ void __init r4k_cache_init(void)
        __flush_cache_all       = r4k___flush_cache_all;
        flush_cache_mm          = r4k_flush_cache_mm;
        flush_cache_page        = r4k_flush_cache_page;
-       __flush_icache_page     = r4k_flush_icache_page;
        flush_cache_range       = r4k_flush_cache_range;
 
        flush_cache_sigtramp    = r4k_flush_cache_sigtramp;
index 16bad7c0a63f876ec0555c247607512bae82dc8a..5537558f19f795d467e327a5225e662ff03dd7b6 100644 (file)
@@ -306,66 +306,6 @@ void sb1_flush_icache_range(unsigned long start, unsigned long end)
        __attribute__((alias("local_sb1_flush_icache_range")));
 #endif
 
-/*
- * Flush the icache for a given physical page.  Need to writeback the
- * dcache first, then invalidate the icache.  If the page isn't
- * executable, nothing is required.
- */
-static void local_sb1_flush_icache_page(struct vm_area_struct *vma,
-       struct page *page)
-{
-       unsigned long start;
-       int cpu = smp_processor_id();
-
-#ifndef CONFIG_SMP
-       if (!(vma->vm_flags & VM_EXEC))
-               return;
-#endif
-
-       /* Need to writeback any dirty data for that page, we have the PA */
-       start = (unsigned long)(page-mem_map) << PAGE_SHIFT;
-       __sb1_writeback_inv_dcache_phys_range(start, start + PAGE_SIZE);
-       /*
-        * If there's a context, bump the ASID (cheaper than a flush,
-        * since we don't know VAs!)
-        */
-       if (vma->vm_mm == current->active_mm) {
-               if (cpu_context(cpu, vma->vm_mm) != 0)
-                       drop_mmu_context(vma->vm_mm, cpu);
-       } else
-               __sb1_flush_icache_range(start, start + PAGE_SIZE);
-
-}
-
-#ifdef CONFIG_SMP
-struct flush_icache_page_args {
-       struct vm_area_struct *vma;
-       struct page *page;
-};
-
-static void sb1_flush_icache_page_ipi(void *info)
-{
-       struct flush_icache_page_args *args = info;
-       local_sb1_flush_icache_page(args->vma, args->page);
-}
-
-/* Dirty dcache could be on another CPU, so do the IPIs */
-static void sb1_flush_icache_page(struct vm_area_struct *vma,
-       struct page *page)
-{
-       struct flush_icache_page_args args;
-
-       if (!(vma->vm_flags & VM_EXEC))
-               return;
-       args.vma = vma;
-       args.page = page;
-       on_each_cpu(sb1_flush_icache_page_ipi, (void *) &args, 1, 1);
-}
-#else
-void sb1_flush_icache_page(struct vm_area_struct *vma, struct page *page)
-       __attribute__((alias("local_sb1_flush_icache_page")));
-#endif
-
 /*
  * A signal trampoline must fit into a single cacheline.
  */
@@ -526,7 +466,6 @@ void sb1_cache_init(void)
 
        /* These routines are for Icache coherence with the Dcache */
        flush_icache_range = sb1_flush_icache_range;
-       __flush_icache_page = sb1_flush_icache_page;
        flush_icache_all = __sb1_flush_icache_all; /* local only */
 
        /* This implies an Icache flush too, so can't be nop'ed */
index 932a09d7ef84810bdb4d43c591d63badbff3892c..f32ebde30ccf1cee1dbe06b29a623b00ea07a744 100644 (file)
@@ -248,33 +248,6 @@ static void tx39_flush_icache_range(unsigned long start, unsigned long end)
        }
 }
 
-/*
- * Ok, this seriously sucks.  We use them to flush a user page but don't
- * know the virtual address, so we have to blast away the whole icache
- * which is significantly more expensive than the real thing.  Otoh we at
- * least know the kernel address of the page so we can flush it
- * selectivly.
- */
-static void tx39_flush_icache_page(struct vm_area_struct *vma, struct page *page)
-{
-       unsigned long addr;
-       /*
-        * If there's no context yet, or the page isn't executable, no icache
-        * flush is needed.
-        */
-       if (!(vma->vm_flags & VM_EXEC))
-               return;
-
-       addr = (unsigned long) page_address(page);
-       tx39_blast_dcache_page(addr);
-
-       /*
-        * We're not sure of the virtual address(es) involved here, so
-        * we have to flush the entire I-cache.
-        */
-       tx39_blast_icache();
-}
-
 static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size)
 {
        unsigned long end;
@@ -382,7 +355,6 @@ void __init tx39_cache_init(void)
                flush_cache_mm          = (void *) tx39h_flush_icache_all;
                flush_cache_range       = (void *) tx39h_flush_icache_all;
                flush_cache_page        = (void *) tx39h_flush_icache_all;
-               __flush_icache_page     = (void *) tx39h_flush_icache_all;
                flush_icache_range      = (void *) tx39h_flush_icache_all;
 
                flush_cache_sigtramp    = (void *) tx39h_flush_icache_all;
@@ -408,7 +380,6 @@ void __init tx39_cache_init(void)
                flush_cache_mm = tx39_flush_cache_mm;
                flush_cache_range = tx39_flush_cache_range;
                flush_cache_page = tx39_flush_cache_page;
-               __flush_icache_page = tx39_flush_icache_page;
                flush_icache_range = tx39_flush_icache_range;
 
                flush_cache_sigtramp = tx39_flush_cache_sigtramp;
index 40c8b0235183859bfc087b72a509db11fdcd4490..caf807ded51415aea2f6d9ba63a7458970f4f3dc 100644 (file)
@@ -25,7 +25,6 @@ void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start,
 void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page,
        unsigned long pfn);
 void (*flush_icache_range)(unsigned long start, unsigned long end);
-void (*__flush_icache_page)(struct vm_area_struct *vma, struct page *page);
 
 /* MIPS specific cache operations */
 void (*flush_cache_sigtramp)(unsigned long addr);
index 5b06349af2d56e84286b62bd2d0af79cdf81185c..88b72c9a84957f2ac787ccf83fa46c4dbb0818d2 100644 (file)
@@ -163,10 +163,10 @@ static int __init page_is_ram(unsigned long pagenr)
 
 void __init paging_init(void)
 {
-       unsigned long zones_size[] = { 0, };
+       unsigned long zones_size[MAX_NR_ZONES] = { 0, };
        unsigned long max_dma, high, low;
 #ifndef CONFIG_FLATMEM
-       unsigned long zholes_size[] = { 0, };
+       unsigned long zholes_size[MAX_NR_ZONES] = { 0, };
        unsigned long i, j, pfn;
 #endif
 
index 9e7f4175b4933504c2f8b2fc9586b7b073b19f68..e99eaa1fbedcc7e7cf54e3ba045382b95c708ad4 100644 (file)
@@ -19,8 +19,8 @@
        move    a0, sp
        REG_S   a2, PT_BVADDR(sp)
        li      a1, \write
-       jal     do_page_fault
-       j       ret_from_exception
+       PTR_LA  ra, ret_from_exception
+       j       do_page_fault
        END(tlb_do_page_fault_\write)
        .endm
 
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 edefa97b233098327e0b6aefbe961403491d9501..3cf0dd4ba548a95a669b563eef477d61a6e4ca9a 100644 (file)
@@ -7,7 +7,6 @@ obj-y                           += pci.o
 #
 # PCI bus host bridge specific code
 #
-obj-$(CONFIG_ITE_BOARD_GEN)    += ops-it8172.o
 obj-$(CONFIG_MIPS_BONITO64)    += ops-bonito64.o
 obj-$(CONFIG_MIPS_GT64111)     += ops-gt64111.o
 obj-$(CONFIG_MIPS_GT64120)     += ops-gt64120.o
@@ -28,8 +27,6 @@ obj-$(CONFIG_LASAT)           += pci-lasat.o
 obj-$(CONFIG_MIPS_ATLAS)       += fixup-atlas.o
 obj-$(CONFIG_MIPS_COBALT)      += fixup-cobalt.o
 obj-$(CONFIG_MIPS_EV64120)     += fixup-ev64120.o
-obj-$(CONFIG_MIPS_ITE8172)     += fixup-ite8172g.o
-obj-$(CONFIG_MIPS_IVR)         += fixup-ivr.o
 obj-$(CONFIG_SOC_AU1500)       += fixup-au1000.o ops-au1000.o
 obj-$(CONFIG_SOC_AU1550)       += fixup-au1000.o ops-au1000.o
 obj-$(CONFIG_SOC_PNX8550)      += fixup-pnx8550.o ops-pnx8550.o
diff --git a/arch/mips/pci/fixup-ite8172g.c b/arch/mips/pci/fixup-ite8172g.c
deleted file mode 100644 (file)
index 2290ea4..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- *     Board specific pci fixups.
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@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.
- */
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <asm/it8172/it8172.h>
-#include <asm/it8172/it8172_pci.h>
-#include <asm/it8172/it8172_int.h>
-
-/*
- * Shortcuts
- */
-#define INTA   IT8172_PCI_INTA_IRQ
-#define INTB   IT8172_PCI_INTB_IRQ
-#define INTC   IT8172_PCI_INTC_IRQ
-#define INTD   IT8172_PCI_INTD_IRQ
-
-static const int internal_func_irqs[7] __initdata = {
-       IT8172_AC97_IRQ,
-       IT8172_DMA_IRQ,
-       IT8172_CDMA_IRQ,
-       IT8172_USB_IRQ,
-       IT8172_BRIDGE_MASTER_IRQ,
-       IT8172_IDE_IRQ,
-       IT8172_MC68K_IRQ
-};
-
-static char irq_tab_ite8172g[][5] __initdata = {
- [0x10] = {    0, INTA, INTB, INTC, INTD },
- [0x11] = {    0, INTA, INTB, INTC, INTD },
- [0x12] = {    0, INTB, INTC, INTD, INTA },
- [0x13] = {    0, INTC, INTD, INTA, INTB },
- [0x14] = {    0, INTD, INTA, INTB, INTC },
-};
-
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
-       /*
-        * Internal device 1 is actually 7 different internal devices on the
-        * IT8172G (a multifunction device).
-        */
-       if (slot == 1)
-               return internal_func_irqs[PCI_FUNC(dev->devfn)];
-
-       return irq_tab_ite8172g[slot][pin];
-}
-
-/* Do platform specific device initialization at pci_enable_device() time */
-int pcibios_plat_dev_init(struct pci_dev *dev)
-{
-       return 0;
-}
diff --git a/arch/mips/pci/fixup-ivr.c b/arch/mips/pci/fixup-ivr.c
deleted file mode 100644 (file)
index 0c7c164..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *     Globespan IVR board-specific pci fixups.
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@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.
- */
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <asm/it8172/it8172.h>
-#include <asm/it8172/it8172_pci.h>
-#include <asm/it8172/it8172_int.h>
-
-/*
- * Shortcuts
- */
-#define INTA   IT8172_PCI_INTA_IRQ
-#define INTB   IT8172_PCI_INTB_IRQ
-#define INTC   IT8172_PCI_INTC_IRQ
-#define INTD   IT8172_PCI_INTD_IRQ
-
-static const int internal_func_irqs[7] __initdata = {
-       IT8172_AC97_IRQ,
-       IT8172_DMA_IRQ,
-       IT8172_CDMA_IRQ,
-       IT8172_USB_IRQ,
-       IT8172_BRIDGE_MASTER_IRQ,
-       IT8172_IDE_IRQ,
-       IT8172_MC68K_IRQ
-};
-
-static char irq_tab_ivr[][5] __initdata = {
- [0x11] = { INTC, INTC, INTD, INTA, INTB },    /* Realtek RTL-8139     */
- [0x12] = { INTB, INTB, INTB, INTC, INTC },    /* IVR slot             */
- [0x13] = { INTA, INTA, INTB, INTC, INTD }     /* Expansion slot       */
-};
-
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
-       if (slot == 1)
-               return internal_func_irqs[PCI_FUNC(dev->devfn)];
-
-       return irq_tab_ivr[slot][pin];
-}
-
-/* Do platform specific device initialization at pci_enable_device() time */
-int pcibios_plat_dev_init(struct pci_dev *dev)
-{
-       return 0;
-}
index 13791b78e59890f525e8600889418b8f5159982a..7a7444874e80341522eb1cadd0c3b2d078d7b8d2 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     arch/mips/pci/fixup-sb1250.c
  *
- *     Copyright (C) 2004  MIPS Technologies, Inc.  All rights reserved.
+ *     Copyright (C) 2004, 2006  MIPS Technologies, Inc.  All rights reserved.
  *         Author:     Maciej W. Rozycki <macro@mips.com>
  *
  *     This program is free software; you can redistribute it and/or
 #include <linux/init.h>
 #include <linux/pci.h>
 
+/*
+ * Set the the BCM1250, etc. PCI host bridge's TRDY timeout
+ * to the finite max.
+ */
+static void __init quirk_sb1250_pci(struct pci_dev *dev)
+{
+       pci_write_config_byte(dev, 0x40, 0xff);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIBYTE, PCI_DEVICE_ID_BCM1250_PCI,
+                       quirk_sb1250_pci);
+
 /*
  * The BCM1250, etc. PCI/HT bridge reports as a host bridge.
  */
@@ -22,3 +33,13 @@ static void __init quirk_sb1250_ht(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIBYTE, PCI_DEVICE_ID_BCM1250_HT,
                        quirk_sb1250_ht);
+
+/*
+ * Set the the SP1011 HT/PCI bridge's TRDY timeout to the finite max.
+ */
+static void __init quirk_sp1011(struct pci_dev *dev)
+{
+       pci_write_config_byte(dev, 0x64, 0xff);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIPACKETS, PCI_DEVICE_ID_SP1011,
+                       quirk_sp1011);
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.
  *
diff --git a/arch/mips/pci/ops-it8172.c b/arch/mips/pci/ops-it8172.c
deleted file mode 100644 (file)
index ba83285..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *     IT8172 system controller specific pci support.
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
- *
- * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
- *
- *  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.
- */
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <asm/it8172/it8172.h>
-#include <asm/it8172/it8172_pci.h>
-
-#define PCI_ACCESS_READ  0
-#define PCI_ACCESS_WRITE 1
-
-#undef DEBUG
-#ifdef DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-static struct resource pci_mem_resource_1;
-
-static struct resource pci_io_resource = {
-       .start  = 0x14018000,
-       .end    = 0x17FFFFFF,
-       .name   = "io pci IO space",
-       .flags  = IORESOURCE_IO
-};
-
-static struct resource pci_mem_resource_0 = {
-       .start  = 0x10101000,
-       .end    = 0x13FFFFFF,
-       .name   = "ext pci memory space 0/1",
-       .flags  = IORESOURCE_MEM,
-       .parent = &pci_mem_resource_0,
-       .sibling = NULL,
-       .child  = &pci_mem_resource_1
-};
-
-static struct resource pci_mem_resource_1 = {
-       .start  = 0x1A000000,
-       .end    = 0x1FBFFFFF,
-       .name   = "ext pci memory space 2/3",
-       .flags  = IORESOURCE_MEM,
-       .parent = &pci_mem_resource_0
-};
-
-extern struct pci_ops it8172_pci_ops;
-
-struct pci_controller it8172_controller = {
-       .pci_ops        = &it8172_pci_ops,
-       .io_resource    = &pci_io_resource,
-       .mem_resource   = &pci_mem_resource_0,
-};
-
-static int it8172_pcibios_config_access(unsigned char access_type,
-                                       struct pci_bus *bus,
-                                       unsigned int devfn, int where,
-                                       u32 * data)
-{
-       /*
-        * config cycles are on 4 byte boundary only
-        */
-
-       /* Setup address */
-       IT_WRITE(IT_CONFADDR, (bus->number << IT_BUSNUM_SHF) |
-                (devfn << IT_FUNCNUM_SHF) | (where & ~0x3));
-
-       if (access_type == PCI_ACCESS_WRITE) {
-               IT_WRITE(IT_CONFDATA, *data);
-       } else {
-               IT_READ(IT_CONFDATA, *data);
-       }
-
-       /*
-        * Revisit: check for master or target abort.
-        */
-       return 0;
-}
-
-
-/*
- * We can't address 8 and 16 bit words directly.  Instead we have to
- * read/write a 32bit word and mask/modify the data we actually want.
- */
-static write_config(struct pci_bus *bus, unsigned int devfn, int where,
-                   int size, u32 val)
-{
-       u32 data = 0;
-
-       switch (size) {
-       case 1:
-               if (it8172_pcibios_config_access
-                   (PCI_ACCESS_READ, dev, where, &data))
-                       return -1;
-
-               *val = (data >> ((where & 3) << 3)) & 0xff;
-
-               return PCIBIOS_SUCCESSFUL;
-
-       case 2:
-
-               if (where & 1)
-                       return PCIBIOS_BAD_REGISTER_NUMBER;
-
-               if (it8172_pcibios_config_access
-                   (PCI_ACCESS_READ, dev, where, &data))
-                       return -1;
-
-               *val = (data >> ((where & 3) << 3)) & 0xffff;
-               DBG("cfg read word: bus %d dev_fn %x where %x: val %x\n",
-                   dev->bus->number, dev->devfn, where, *val);
-
-               return PCIBIOS_SUCCESSFUL;
-
-       case 4:
-
-               if (where & 3)
-                       return PCIBIOS_BAD_REGISTER_NUMBER;
-
-               if (it8172_pcibios_config_access
-                   (PCI_ACCESS_READ, dev, where, &data))
-                       return -1;
-
-               *val = data;
-
-               return PCIBIOS_SUCCESSFUL;
-       }
-}
-
-
-static write_config(struct pci_bus *bus, unsigned int devfn, int where,
-                   int size, u32 val)
-{
-       u32 data = 0;
-
-       switch (size) {
-       case 1:
-               if (it8172_pcibios_config_access
-                   (PCI_ACCESS_READ, dev, where, &data))
-                       return -1;
-
-               data = (data & ~(0xff << ((where & 3) << 3))) |
-                   (val << ((where & 3) << 3));
-
-               if (it8172_pcibios_config_access
-                   (PCI_ACCESS_WRITE, dev, where, &data))
-                       return -1;
-
-               return PCIBIOS_SUCCESSFUL;
-
-       case 2:
-               if (where & 1)
-                       return PCIBIOS_BAD_REGISTER_NUMBER;
-
-               if (it8172_pcibios_config_access
-                   (PCI_ACCESS_READ, dev, where, &data))
-                       eturn - 1;
-
-               data = (data & ~(0xffff << ((where & 3) << 3))) |
-                   (val << ((where & 3) << 3));
-
-               if (it8172_pcibios_config_access
-                   (PCI_ACCESS_WRITE, dev, where, &data))
-                       return -1;
-
-               return PCIBIOS_SUCCESSFUL;
-
-       case 4:
-               if (where & 3)
-                       return PCIBIOS_BAD_REGISTER_NUMBER;
-
-               if (it8172_pcibios_config_access
-                   (PCI_ACCESS_WRITE, dev, where, &val))
-                       return -1;
-
-               return PCIBIOS_SUCCESSFUL;
-       }
-}
-
-struct pci_ops it8172_pci_ops = {
-       .read = read_config,
-       .write = write_config,
-};
index 8134220ed600211a41801d1962ab71d1f9db9dfe..7a941ecff3bbd505066013f125118b55c9c0d39f 100644 (file)
@@ -123,7 +123,8 @@ static inline void power_button(void)
        if (machine_state & MACHINE_PANICED)
                return;
 
-       if ((machine_state & MACHINE_SHUTTING_DOWN) || kill_proc(1,SIGINT,1)) {
+       if ((machine_state & MACHINE_SHUTTING_DOWN) ||
+                       kill_cad_pid(SIGINT, 1)) {
                /* No init process or button pressed twice.  */
                sgi_machine_power_off();
        }
index 79ddb460565955a60864472b818ef2d00808fef7..fd0932b2d5218ef58a08a79056c5f2af68c23d61 100644 (file)
@@ -120,7 +120,7 @@ static inline void ip32_power_button(void)
        if (has_panicked)
                return;
 
-       if (shuting_down || kill_proc(1, SIGINT, 1)) {
+       if (shuting_down || kill_cad_pid(SIGINT, 1)) {
                /* No init process or button pressed twice.  */
                ip32_machine_power_off();
        }
index a0222fa4416cb62537302e01c4b5ed6a3436d491..a46b75b23ecb1e2ef10f4470279764f23905dacc 100644 (file)
@@ -482,7 +482,7 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
        write_c0_compare(read_c0_count());
 #endif
 
-       pending = read_c0_cause();
+       pending = read_c0_cause() & read_c0_status();
 
 #ifdef CONFIG_SIBYTE_BCM1480_PROF
        if (pending & CAUSEF_IP7)       /* Cpu performance counter interrupt */
index a451b4c7732d9baae2127529c74f974cf2154278..f9bd9f074517575cae863c3b03b2200d22c5677a 100644 (file)
@@ -442,7 +442,7 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
         * blasting the high 32 bits.
         */
 
-       pending = read_c0_cause();
+       pending = read_c0_cause() & read_c0_status();
 
 #ifdef CONFIG_SIBYTE_SB1250_PROF
        if (pending & CAUSEF_IP7) /* Cpu performance counter interrupt */
@@ -476,5 +476,8 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
                                              R_IMR_INTERRUPT_STATUS_BASE)));
                if (mask)
                        do_IRQ(fls64(mask) - 1, regs);
-       }
+               else
+                       spurious_interrupt(regs);
+       } else
+               spurious_interrupt(regs);
 }
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 6dd0ea8f88e0a49c273e3f04734efc3e42abb0d5..d2101237442e8bbfa345788f4b49c950d6848a17 100644 (file)
@@ -127,7 +127,7 @@ config PA11
 
 config PREFETCH
        def_bool y
-       depends on PA8X00
+       depends on PA8X00 || PA7200
 
 config 64BIT
        bool "64-bit kernel"
index d7c80edf44899323f7401c59fd8e1c64be5648f6..2d58b92b57e368094635d1d4431bdcb782ed6d40 100644 (file)
@@ -77,22 +77,26 @@ static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
 {
        struct hpux_dirent * dirent;
        struct getdents_callback * buf = (struct getdents_callback *) __buf;
+       ino_t d_ino;
        int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
 
        buf->error = -EINVAL;   /* only used if we fail.. */
        if (reclen > buf->count)
                return -EINVAL;
+       d_ino = ino;
+       if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+               return -EOVERFLOW;
        dirent = buf->previous;
        if (dirent)
                put_user(offset, &dirent->d_off);
        dirent = buf->current_dir;
        buf->previous = dirent;
-       put_user(ino, &dirent->d_ino);
+       put_user(d_ino, &dirent->d_ino);
        put_user(reclen, &dirent->d_reclen);
        put_user(namlen, &dirent->d_namlen);
        copy_to_user(dirent->d_name, name, namlen);
        put_user(0, dirent->d_name + namlen);
-       ((char *) dirent) += reclen;
+       dirent = (void __user *)dirent + reclen;
        buf->current_dir = dirent;
        buf->count -= reclen;
        return 0;
index cb69727027aecf66889bad82a29e947bf87cb994..2e2dc4f2c853edee44818110eee1d44e5d85d1b9 100644 (file)
@@ -266,16 +266,21 @@ static int hpux_uname(struct hpux_utsname *name)
 
        down_read(&uts_sem);
 
-       error = __copy_to_user(&name->sysname,&system_utsname.sysname,HPUX_UTSLEN-1);
-       error |= __put_user(0,name->sysname+HPUX_UTSLEN-1);
-       error |= __copy_to_user(&name->nodename,&system_utsname.nodename,HPUX_UTSLEN-1);
-       error |= __put_user(0,name->nodename+HPUX_UTSLEN-1);
-       error |= __copy_to_user(&name->release,&system_utsname.release,HPUX_UTSLEN-1);
-       error |= __put_user(0,name->release+HPUX_UTSLEN-1);
-       error |= __copy_to_user(&name->version,&system_utsname.version,HPUX_UTSLEN-1);
-       error |= __put_user(0,name->version+HPUX_UTSLEN-1);
-       error |= __copy_to_user(&name->machine,&system_utsname.machine,HPUX_UTSLEN-1);
-       error |= __put_user(0,name->machine+HPUX_UTSLEN-1);
+       error = __copy_to_user(&name->sysname, &utsname()->sysname,
+                              HPUX_UTSLEN - 1);
+       error |= __put_user(0, name->sysname + HPUX_UTSLEN - 1);
+       error |= __copy_to_user(&name->nodename, &utsname()->nodename,
+                               HPUX_UTSLEN - 1);
+       error |= __put_user(0, name->nodename + HPUX_UTSLEN - 1);
+       error |= __copy_to_user(&name->release, &utsname()->release,
+                               HPUX_UTSLEN - 1);
+       error |= __put_user(0, name->release + HPUX_UTSLEN - 1);
+       error |= __copy_to_user(&name->version, &utsname()->version,
+                               HPUX_UTSLEN - 1);
+       error |= __put_user(0, name->version + HPUX_UTSLEN - 1);
+       error |= __copy_to_user(&name->machine, &utsname()->machine,
+                               HPUX_UTSLEN - 1);
+       error |= __put_user(0, name->machine + HPUX_UTSLEN - 1);
 
        up_read(&uts_sem);
 
@@ -373,8 +378,8 @@ int hpux_utssys(char *ubuf, int n, int type)
                /*  TODO:  print a warning about using this?  */
                down_write(&uts_sem);
                error = -EFAULT;
-               if (!copy_from_user(system_utsname.sysname, ubuf, len)) {
-                       system_utsname.sysname[len] = 0;
+               if (!copy_from_user(utsname()->sysname, ubuf, len)) {
+                       utsname()->sysname[len] = 0;
                        error = 0;
                }
                up_write(&uts_sem);
@@ -400,8 +405,8 @@ int hpux_utssys(char *ubuf, int n, int type)
                /*  TODO:  print a warning about this?  */
                down_write(&uts_sem);
                error = -EFAULT;
-               if (!copy_from_user(system_utsname.release, ubuf, len)) {
-                       system_utsname.release[len] = 0;
+               if (!copy_from_user(utsname()->release, ubuf, len)) {
+                       utsname()->release[len] = 0;
                        error = 0;
                }
                up_write(&uts_sem);
@@ -422,13 +427,13 @@ int hpux_getdomainname(char *name, int len)
        
        down_read(&uts_sem);
        
-       nlen = strlen(system_utsname.domainname) + 1;
+       nlen = strlen(utsname()->domainname) + 1;
 
        if (nlen < len)
                len = nlen;
        if(len > __NEW_UTS_LEN)
                goto done;
-       if(copy_to_user(name, system_utsname.domainname, len))
+       if(copy_to_user(name, utsname()->domainname, len))
                goto done;
        err = 0;
 done:
index d1833f164bbeaad34084dc92cfc82882e6759efb..1e64e7b88110157df77334416f7d8a703bea4449 100644 (file)
@@ -87,7 +87,7 @@ struct elf_prpsinfo32
  */
 
 #define SET_PERSONALITY(ex, ibcs2) \
-       current->personality = PER_LINUX32; \
+       set_thread_flag(TIF_32BIT); \
        current->thread.map_base = DEFAULT_MAP_BASE32; \
        current->thread.task_size = DEFAULT_TASK_SIZE32 \
 
@@ -102,25 +102,3 @@ cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
 }
 
 #include "../../../fs/binfmt_elf.c"
-
-/* Set up a separate execution domain for ELF32 binaries running
- * on an ELF64 kernel */
-
-static struct exec_domain parisc32_exec_domain = { 
-       .name = "Linux/ELF32",
-       .pers_low = PER_LINUX32,
-       .pers_high = PER_LINUX32,
-};      
-
-static int __init parisc32_exec_init(void)
-{
-       /* steal the identity signal mappings from the default domain */
-       parisc32_exec_domain.signal_map = default_exec_domain.signal_map;
-       parisc32_exec_domain.signal_invmap = default_exec_domain.signal_invmap;
-
-       register_exec_domain(&parisc32_exec_domain);
-
-       return 0;
-}
-
-__initcall(parisc32_exec_init);
index bc7c4a4e26a1e24f53b62b735bf820baac104635..0be51e92a2fc62f1e82387249d3dbead462606d7 100644 (file)
@@ -35,15 +35,12 @@ int icache_stride __read_mostly;
 EXPORT_SYMBOL(dcache_stride);
 
 
-#if defined(CONFIG_SMP)
 /* On some machines (e.g. ones with the Merced bus), there can be
  * only a single PxTLB broadcast at a time; this must be guaranteed
  * by software.  We put a spinlock around all TLB flushes  to
  * ensure this.
  */
 DEFINE_SPINLOCK(pa_tlb_lock);
-EXPORT_SYMBOL(pa_tlb_lock);
-#endif
 
 struct pdc_cache_info cache_info __read_mostly;
 #ifndef CONFIG_PA20
@@ -91,7 +88,8 @@ update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
 
                flush_kernel_dcache_page(page);
                clear_bit(PG_dcache_dirty, &page->flags);
-       }
+       } else if (parisc_requires_coherency())
+               flush_kernel_dcache_page(page);
 }
 
 void
@@ -370,3 +368,45 @@ void parisc_setup_cache_timing(void)
 
        printk(KERN_INFO "Setting cache flush threshold to %x (%d CPUs online)\n", parisc_cache_flush_threshold, num_online_cpus());
 }
+
+extern void purge_kernel_dcache_page(unsigned long);
+extern void clear_user_page_asm(void *page, unsigned long vaddr);
+
+void clear_user_page(void *page, unsigned long vaddr, struct page *pg)
+{
+       purge_kernel_dcache_page((unsigned long)page);
+       purge_tlb_start();
+       pdtlb_kernel(page);
+       purge_tlb_end();
+       clear_user_page_asm(page, vaddr);
+}
+EXPORT_SYMBOL(clear_user_page);
+
+void flush_kernel_dcache_page_addr(void *addr)
+{
+       flush_kernel_dcache_page_asm(addr);
+       purge_tlb_start();
+       pdtlb_kernel(addr);
+       purge_tlb_end();
+}
+EXPORT_SYMBOL(flush_kernel_dcache_page_addr);
+
+void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
+                   struct page *pg)
+{
+       /* no coherency needed (all in kmap/kunmap) */
+       copy_user_page_asm(vto, vfrom);
+       if (!parisc_requires_coherency())
+               flush_kernel_dcache_page_asm(vto);
+}
+EXPORT_SYMBOL(copy_user_page);
+
+#ifdef CONFIG_PA8X00
+
+void kunmap_parisc(void *addr)
+{
+       if (parisc_requires_coherency())
+               flush_kernel_dcache_page_addr(addr);
+}
+EXPORT_SYMBOL(kunmap_parisc);
+#endif
index 95c1b8ec428966f4e42491ae89ebef6202819db0..340b5e8d67bad1197b75b4ec5320a932575f21e4 100644 (file)
@@ -30,6 +30,7 @@
 
 
 #include <asm/psw.h>
+#include <asm/cache.h>         /* for L1_CACHE_SHIFT */
 #include <asm/assembly.h>      /* for LDREG/STREG defines */
 #include <asm/pgtable.h>
 #include <asm/signal.h>
        bb,>=,n         \pmd,_PxD_PRESENT_BIT,\fault
        DEP             %r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */
        copy            \pmd,%r9
-#ifdef CONFIG_64BIT
-       shld            %r9,PxD_VALUE_SHIFT,\pmd
-#else
-       shlw            %r9,PxD_VALUE_SHIFT,\pmd
-#endif
+       SHLREG          %r9,PxD_VALUE_SHIFT,\pmd
        EXTR            \va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index
        DEP             %r0,31,PAGE_SHIFT,\pmd  /* clear offset */
        shladd          \index,BITS_PER_PTE_ENTRY,\pmd,\pmd
@@ -941,8 +938,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)
@@ -970,11 +967,7 @@ intr_return:
        /* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) amount
        ** irq_stat[] is defined using ____cacheline_aligned.
        */
-#ifdef CONFIG_64BIT
-       shld    %r1, 6, %r20
-#else
-       shlw    %r1, 5, %r20
-#endif
+       SHLREG  %r1,L1_CACHE_SHIFT,%r20
        add     %r19,%r20,%r19  /* now have &irq_stat[smp_processor_id()] */
 #endif /* CONFIG_SMP */
 
@@ -1076,7 +1069,7 @@ intr_do_preempt:
        BL      preempt_schedule_irq, %r2
        nop
 
-       b       intr_restore            /* ssm PSW_SM_I done by intr_restore */
+       b,n     intr_restore            /* ssm PSW_SM_I done by intr_restore */
 #endif /* CONFIG_PREEMPT */
 
        .import do_signal,code
@@ -2115,11 +2108,7 @@ syscall_check_bh:
        ldw     TI_CPU-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26 /* cpu # */
 
        /* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) bits */
-#ifdef CONFIG_64BIT
-       shld    %r26, 6, %r20
-#else
-       shlw    %r26, 5, %r20
-#endif
+       SHLREG  %r26,L1_CACHE_SHIFT,%r20
        add     %r19,%r20,%r19  /* now have &irq_stat[smp_processor_id()] */
 #endif /* CONFIG_SMP */
 
index 3058bffd8a2c80bfcb1a0f42ca0579a63d792071..18ba4cb9159b22a2d3ae1f3462e3761336a76a97 100644 (file)
@@ -231,6 +231,7 @@ static struct hp_hardware hp_hardware_list[] __initdata = {
        {HPHW_NPROC,0x5E6,0x4,0x91,"Keystone/Matterhorn W2 650"},
        {HPHW_NPROC,0x5E7,0x4,0x91,"Caribe W2 800"},
        {HPHW_NPROC,0x5E8,0x4,0x91,"Pikes Peak W2"},
+       {HPHW_NPROC,0x5EB,0x4,0x91,"Perf/Leone 875 W2+"},
        {HPHW_NPROC,0x5FF,0x4,0x91,"Hitachi W"},
        {HPHW_NPROC,0x600,0x4,0x81,"Gecko (712/60)"},
        {HPHW_NPROC,0x601,0x4,0x81,"Gecko 80 (712/80)"},
@@ -584,8 +585,10 @@ static struct hp_hardware hp_hardware_list[] __initdata = {
        {HPHW_CONSOLE, 0x01A, 0x0001F, 0x00, "Jason/Anole 64 Null Console"}, 
        {HPHW_CONSOLE, 0x01B, 0x0001F, 0x00, "Jason/Anole 100 Null Console"}, 
        {HPHW_FABRIC, 0x004, 0x000AA, 0x80, "Halfdome DNA Central Agent"}, 
+       {HPHW_FABRIC, 0x005, 0x000AA, 0x80, "Keystone DNA Central Agent"},
        {HPHW_FABRIC, 0x007, 0x000AA, 0x80, "Caribe DNA Central Agent"}, 
        {HPHW_FABRIC, 0x004, 0x000AB, 0x00, "Halfdome TOGO Fabric Crossbar"}, 
+       {HPHW_FABRIC, 0x005, 0x000AB, 0x00, "Keystone TOGO Fabric Crossbar"},
        {HPHW_FABRIC, 0x004, 0x000AC, 0x00, "Halfdome Sakura Fabric Router"}, 
        {HPHW_FIO, 0x025, 0x0002E, 0x80, "Armyknife Optional X.25"}, 
        {HPHW_FIO, 0x004, 0x0004F, 0x0, "8-Port X.25 EISA-ACC (AMSO)"}, 
index 5b8803cc3d69498c1bc916cee4bfd4467d14b61f..9bdd0197ceb777f555efc995e1581c17d2167938 100644 (file)
@@ -45,6 +45,17 @@ extern irqreturn_t ipi_interrupt(int, void *, struct pt_regs *);
 */
 static volatile unsigned long cpu_eiem = 0;
 
+/*
+** ack bitmap ... habitually set to 1, but reset to zero
+** between ->ack() and ->end() of the interrupt to prevent
+** re-interruption of a processing interrupt.
+*/
+static volatile unsigned long global_ack_eiem = ~0UL;
+/*
+** Local bitmap, same as above but for per-cpu interrupts
+*/
+static DEFINE_PER_CPU(unsigned long, local_ack_eiem) = ~0UL;
+
 static void cpu_disable_irq(unsigned int irq)
 {
        unsigned long eirr_bit = EIEM_MASK(irq);
@@ -62,13 +73,6 @@ static void cpu_enable_irq(unsigned int irq)
 
        cpu_eiem |= eirr_bit;
 
-       /* FIXME: while our interrupts aren't nested, we cannot reset
-        * the eiem mask if we're already in an interrupt.  Once we
-        * implement nested interrupts, this can go away
-        */
-       if (!in_interrupt())
-               set_eiem(cpu_eiem);
-
        /* This is just a simple NOP IPI.  But what it does is cause
         * all the other CPUs to do a set_eiem(cpu_eiem) at the end
         * of the interrupt handler */
@@ -84,13 +88,45 @@ static unsigned int cpu_startup_irq(unsigned int irq)
 void no_ack_irq(unsigned int irq) { }
 void no_end_irq(unsigned int irq) { }
 
+void cpu_ack_irq(unsigned int irq)
+{
+       unsigned long mask = EIEM_MASK(irq);
+       int cpu = smp_processor_id();
+
+       /* Clear in EIEM so we can no longer process */
+       if (CHECK_IRQ_PER_CPU(irq_desc[irq].status))
+               per_cpu(local_ack_eiem, cpu) &= ~mask;
+       else
+               global_ack_eiem &= ~mask;
+
+       /* disable the interrupt */
+       set_eiem(cpu_eiem & global_ack_eiem & per_cpu(local_ack_eiem, cpu));
+       /* and now ack it */
+       mtctl(mask, 23);
+}
+
+void cpu_end_irq(unsigned int irq)
+{
+       unsigned long mask = EIEM_MASK(irq);
+       int cpu = smp_processor_id();
+
+       /* set it in the eiems---it's no longer in process */
+       if (CHECK_IRQ_PER_CPU(irq_desc[irq].status))
+               per_cpu(local_ack_eiem, cpu) |= mask;
+       else
+               global_ack_eiem |= mask;
+
+       /* enable the interrupt */
+       set_eiem(cpu_eiem & global_ack_eiem & per_cpu(local_ack_eiem, cpu));
+}
+
 #ifdef CONFIG_SMP
 int cpu_check_affinity(unsigned int irq, cpumask_t *dest)
 {
        int cpu_dest;
 
        /* timer and ipi have to always be received on all CPUs */
-       if (irq == TIMER_IRQ || irq == IPI_IRQ) {
+       if (CHECK_IRQ_PER_CPU(irq)) {
                /* Bad linux design decision.  The mask has already
                 * been set; we must reset it */
                irq_desc[irq].affinity = CPU_MASK_ALL;
@@ -119,8 +155,8 @@ static struct hw_interrupt_type cpu_interrupt_type = {
        .shutdown       = cpu_disable_irq,
        .enable         = cpu_enable_irq,
        .disable        = cpu_disable_irq,
-       .ack            = no_ack_irq,
-       .end            = no_end_irq,
+       .ack            = cpu_ack_irq,
+       .end            = cpu_end_irq,
 #ifdef CONFIG_SMP
        .set_affinity   = cpu_set_affinity_irq,
 #endif
@@ -209,7 +245,7 @@ int show_interrupts(struct seq_file *p, void *v)
 ** Then use that to get the Transaction address and data.
 */
 
-int cpu_claim_irq(unsigned int irq, struct hw_interrupt_type *type, void *data)
+int cpu_claim_irq(unsigned int irq, struct irq_chip *type, void *data)
 {
        if (irq_desc[irq].action)
                return -EBUSY;
@@ -298,82 +334,69 @@ unsigned int txn_alloc_data(unsigned int virt_irq)
        return virt_irq - CPU_IRQ_BASE;
 }
 
+static inline int eirr_to_irq(unsigned long eirr)
+{
+#ifdef CONFIG_64BIT
+       int bit = fls64(eirr);
+#else
+       int bit = fls(eirr);
+#endif
+       return (BITS_PER_LONG - bit) + TIMER_IRQ;
+}
+
 /* ONLY called from entry.S:intr_extint() */
 void do_cpu_irq_mask(struct pt_regs *regs)
 {
        unsigned long eirr_val;
-
-       irq_enter();
-
-       /*
-        * Don't allow TIMER or IPI nested interrupts.
-        * Allowing any single interrupt to nest can lead to that CPU
-        * handling interrupts with all enabled interrupts unmasked.
-        */
-       set_eiem(0UL);
-
-       /* 1) only process IRQs that are enabled/unmasked (cpu_eiem)
-        * 2) We loop here on EIRR contents in order to avoid
-        *    nested interrupts or having to take another interrupt
-        *    when we could have just handled it right away.
-        */
-       for (;;) {
-               unsigned long bit = (1UL << (BITS_PER_LONG - 1));
-               unsigned int irq;
-               eirr_val = mfctl(23) & cpu_eiem;
-               if (!eirr_val)
-                       break;
-
-               mtctl(eirr_val, 23); /* reset bits we are going to process */
-
-               /* Work our way from MSb to LSb...same order we alloc EIRs */
-               for (irq = TIMER_IRQ; eirr_val && bit; bit>>=1, irq++) {
+       int irq, cpu = smp_processor_id();
 #ifdef CONFIG_SMP
-                       cpumask_t dest = irq_desc[irq].affinity;
+       cpumask_t dest;
 #endif
-                       if (!(bit & eirr_val))
-                               continue;
 
-                       /* clear bit in mask - can exit loop sooner */
-                       eirr_val &= ~bit;
+       local_irq_disable();
+       irq_enter();
 
-#ifdef CONFIG_SMP
-                       /* FIXME: because generic set affinity mucks
-                        * with the affinity before sending it to us
-                        * we can get the situation where the affinity is
-                        * wrong for our CPU type interrupts */
-                       if (irq != TIMER_IRQ && irq != IPI_IRQ &&
-                           !cpu_isset(smp_processor_id(), dest)) {
-                               int cpu = first_cpu(dest);
-
-                               printk(KERN_DEBUG "redirecting irq %d from CPU %d to %d\n",
-                                      irq, smp_processor_id(), cpu);
-                               gsc_writel(irq + CPU_IRQ_BASE,
-                                          cpu_data[cpu].hpa);
-                               continue;
-                       }
-#endif
+       eirr_val = mfctl(23) & cpu_eiem & global_ack_eiem &
+               per_cpu(local_ack_eiem, cpu);
+       if (!eirr_val)
+               goto set_out;
+       irq = eirr_to_irq(eirr_val);
 
-                       __do_IRQ(irq, regs);
-               }
+#ifdef CONFIG_SMP
+       dest = irq_desc[irq].affinity;
+       if (CHECK_IRQ_PER_CPU(irq_desc[irq].status) &&
+           !cpu_isset(smp_processor_id(), dest)) {
+               int cpu = first_cpu(dest);
+
+               printk(KERN_DEBUG "redirecting irq %d from CPU %d to %d\n",
+                      irq, smp_processor_id(), cpu);
+               gsc_writel(irq + CPU_IRQ_BASE,
+                          cpu_data[cpu].hpa);
+               goto set_out;
        }
+#endif
+       __do_IRQ(irq, regs);
 
-       set_eiem(cpu_eiem);     /* restore original mask */
+ out:
        irq_exit();
-}
+       return;
 
+ set_out:
+       set_eiem(cpu_eiem & global_ack_eiem & per_cpu(local_ack_eiem, cpu));
+       goto out;
+}
 
 static struct irqaction timer_action = {
        .handler = timer_interrupt,
        .name = "timer",
-       .flags = IRQF_DISABLED,
+       .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_PERCPU,
 };
 
 #ifdef CONFIG_SMP
 static struct irqaction ipi_action = {
        .handler = ipi_interrupt,
        .name = "IPI",
-       .flags = IRQF_DISABLED,
+       .flags = IRQF_DISABLED | IRQF_PERCPU,
 };
 #endif
 
index 0b485ef4be89e8b1c9d655e19fa59aca1f29c41a..2f9f9dfa66f7ba557d2a9158ffae6cfbe13a29dd 100644 (file)
@@ -368,7 +368,14 @@ out:
        return error;
 }
 
-unsigned long 
+extern int __execve(const char *filename, char *const argv[],
+               char *const envp[], struct task_struct *task);
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+       return __execve(filename, argv, envp, current);
+}
+
+unsigned long
 get_wchan(struct task_struct *p)
 {
        struct unwind_frame_info info;
index 99d7fca9310475c51e89520b64cffa1e63fecf58..fb81e5687e7c8a69c456a816c179cc26840d3239 100644 (file)
@@ -143,8 +143,9 @@ static int __init processor_probe(struct parisc_device *dev)
        p = &cpu_data[cpuid];
        boot_cpu_data.cpu_count++;
 
-       /* initialize counters */
-       memset(p, 0, sizeof(struct cpuinfo_parisc));
+       /* initialize counters - CPU 0 gets it_value set in time_init() */
+       if (cpuid)
+               memset(p, 0, sizeof(struct cpuinfo_parisc));
 
        p->loops_per_jiffy = loops_per_jiffy;
        p->dev = dev;           /* Save IODC data in case we need it */
index bb83880c5ee3458bd9940b96e527bf9146cb96e9..ee6653edeb7a1b83da64572c03d9d0620319558f 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/stddef.h>
 #include <linux/compat.h>
 #include <linux/elf.h>
-#include <linux/personality.h>
 #include <asm/ucontext.h>
 #include <asm/rt_sigframe.h>
 #include <asm/uaccess.h>
@@ -433,13 +432,13 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        if (in_syscall) {
                regs->gr[31] = haddr;
 #ifdef __LP64__
-               if (personality(current->personality) == PER_LINUX)
+               if (!test_thread_flag(TIF_32BIT))
                        sigframe_size |= 1;
 #endif
        } else {
                unsigned long psw = USER_PSW;
 #ifdef __LP64__
-               if (personality(current->personality) == PER_LINUX)
+               if (!test_thread_flag(TIF_32BIT))
                        psw |= PSW_W;
 #endif
 
index 98e40959a564815df35e2d57272c3deb0e2d2d8c..faad338f310ed12f8dddc4f4824b40c61edde298 100644 (file)
@@ -262,6 +262,9 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                                        this_cpu, which);
                                return IRQ_NONE;
                        } /* Switch */
+               /* let in any pending interrupts */
+               local_irq_enable();
+               local_irq_disable();
                } /* while (ops) */
        }
        return IRQ_HANDLED;
@@ -430,8 +433,9 @@ smp_do_timer(struct pt_regs *regs)
 static void __init
 smp_cpu_init(int cpunum)
 {
-       extern int init_per_cpu(int);  /* arch/parisc/kernel/setup.c */
+       extern int init_per_cpu(int);  /* arch/parisc/kernel/processor.c */
        extern void init_IRQ(void);    /* arch/parisc/kernel/irq.c */
+       extern void start_cpu_itimer(void); /* arch/parisc/kernel/time.c */
 
        /* Set modes and Enable floating point coprocessor */
        (void) init_per_cpu(cpunum);
@@ -457,6 +461,7 @@ smp_cpu_init(int cpunum)
        enter_lazy_tlb(&init_mm, current);
 
        init_IRQ();   /* make sure no IRQ's are enabled or pending */
+       start_cpu_itimer();
 }
 
 
index 8b5df98e2b3158a229226cdb233e43349c950e4c..1db5588ceacf7474ebba8d947b6b7c31da09a906 100644 (file)
@@ -31,6 +31,8 @@
 #include <linux/shm.h>
 #include <linux/smp_lock.h>
 #include <linux/syscalls.h>
+#include <linux/utsname.h>
+#include <linux/personality.h>
 
 int sys_pipe(int __user *fildes)
 {
@@ -248,3 +250,46 @@ asmlinkage int sys_free_hugepages(unsigned long addr)
 {
        return -EINVAL;
 }
+
+long parisc_personality(unsigned long personality)
+{
+       long err;
+
+       if (personality(current->personality) == PER_LINUX32
+           && personality == PER_LINUX)
+               personality = PER_LINUX32;
+
+       err = sys_personality(personality);
+       if (err == PER_LINUX32)
+               err = PER_LINUX;
+
+       return err;
+}
+
+static inline int override_machine(char __user *mach) {
+#ifdef CONFIG_COMPAT
+       if (personality(current->personality) == PER_LINUX32) {
+               if (__put_user(0, mach + 6) ||
+                   __put_user(0, mach + 7))
+                       return -EFAULT;
+       }
+
+       return 0;
+#else /*!CONFIG_COMPAT*/
+       return 0;
+#endif /*CONFIG_COMPAT*/
+}
+
+long parisc_newuname(struct new_utsname __user *utsname)
+{
+       int err = 0;
+
+       down_read(&uts_sem);
+       if (copy_to_user(utsname, &system_utsname, sizeof(*utsname)))
+               err = -EFAULT;
+       up_read(&uts_sem);
+
+       err = override_machine(utsname->machine);
+
+       return (long)err;
+}
index b74869803081900be006855604f941664a46d157..e3b30bc36453a0d05b830c3d9967de27112ab0c3 100644 (file)
@@ -237,14 +237,19 @@ int sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user
 
 int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
 {
+       compat_ino_t ino;
        int err;
 
        if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) ||
            !new_valid_dev(stat->rdev))
                return -EOVERFLOW;
 
+       ino = stat->ino;
+       if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
+               return -EOVERFLOW;
+
        err  = put_user(new_encode_dev(stat->dev), &statbuf->st_dev);
-       err |= put_user(stat->ino, &statbuf->st_ino);
+       err |= put_user(ino, &statbuf->st_ino);
        err |= put_user(stat->mode, &statbuf->st_mode);
        err |= put_user(stat->nlink, &statbuf->st_nlink);
        err |= put_user(0, &statbuf->st_reserved1);
@@ -312,16 +317,20 @@ filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
        struct linux32_dirent __user * dirent;
        struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
        int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4);
+       u32 d_ino;
 
        buf->error = -EINVAL;   /* only used if we fail.. */
        if (reclen > buf->count)
                return -EINVAL;
+       d_ino = ino;
+       if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+               return -EOVERFLOW;
        dirent = buf->previous;
        if (dirent)
                put_user(offset, &dirent->d_off);
        dirent = buf->current_dir;
        buf->previous = dirent;
-       put_user(ino, &dirent->d_ino);
+       put_user(d_ino, &dirent->d_ino);
        put_user(reclen, &dirent->d_reclen);
        copy_to_user(dirent->d_name, name, namlen);
        put_user(0, dirent->d_name + namlen);
@@ -371,12 +380,16 @@ fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t
 {
        struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
        struct old_linux32_dirent __user * dirent;
+       u32 d_ino;
 
        if (buf->count)
                return -EINVAL;
+       d_ino = ino;
+       if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+               return -EOVERFLOW;
        buf->count++;
        dirent = buf->dirent;
-       put_user(ino, &dirent->d_ino);
+       put_user(d_ino, &dirent->d_ino);
        put_user(offset, &dirent->d_offset);
        put_user(namlen, &dirent->d_namlen);
        copy_to_user(dirent->d_name, name, namlen);
index e27b432f90a8628a5eb2c397d7b1e2ff7f4be8cf..701d66a596e8855d22ab3ddaa4a889b68b4500ce 100644 (file)
        ENTRY_SAME(socketpair)
        ENTRY_SAME(setpgid)
        ENTRY_SAME(send)
-       ENTRY_SAME(newuname)
+       ENTRY_OURS(newuname)
        ENTRY_SAME(umask)               /* 60 */
        ENTRY_SAME(chroot)
        ENTRY_SAME(ustat)
        ENTRY_SAME(fchdir)
        ENTRY_SAME(bdflush)
        ENTRY_SAME(sysfs)               /* 135 */
-       ENTRY_SAME(personality)
+       ENTRY_OURS(personality)
        ENTRY_SAME(ni_syscall)  /* for afs_syscall */
        ENTRY_SAME(setfsuid)
        ENTRY_SAME(setfsgid)
index ab641d67f5516fc6fb494799edce9db1f13f08d0..b3496b592a2d7db687793899388a4db9ce73f064 100644 (file)
@@ -32,8 +32,7 @@
 
 #include <linux/timex.h>
 
-static long clocktick __read_mostly;   /* timer cycles per tick */
-static long halftick __read_mostly;
+static unsigned long clocktick __read_mostly;  /* timer cycles per tick */
 
 #ifdef CONFIG_SMP
 extern void smp_do_timer(struct pt_regs *regs);
@@ -41,46 +40,106 @@ extern void smp_do_timer(struct pt_regs *regs);
 
 irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-       long now;
-       long next_tick;
-       int nticks;
-       int cpu = smp_processor_id();
+       unsigned long now;
+       unsigned long next_tick;
+       unsigned long cycles_elapsed;
+       unsigned long cycles_remainder;
+       unsigned int cpu = smp_processor_id();
+
+       /* gcc can optimize for "read-only" case with a local clocktick */
+       unsigned long cpt = clocktick;
 
        profile_tick(CPU_PROFILING, regs);
 
-       now = mfctl(16);
-       /* initialize next_tick to time at last clocktick */
+       /* Initialize next_tick to the expected tick time. */
        next_tick = cpu_data[cpu].it_value;
 
-       /* since time passes between the interrupt and the mfctl()
-        * above, it is never true that last_tick + clocktick == now.  If we
-        * never miss a clocktick, we could set next_tick = last_tick + clocktick
-        * but maybe we'll miss ticks, hence the loop.
-        *
-        * Variables are *signed*.
+       /* Get current interval timer.
+        * CR16 reads as 64 bits in CPU wide mode.
+        * CR16 reads as 32 bits in CPU narrow mode.
         */
+       now = mfctl(16);
+
+       cycles_elapsed = now - next_tick;
 
-       nticks = 0;
-       while((next_tick - now) < halftick) {
-               next_tick += clocktick;
-               nticks++;
+       if ((cycles_elapsed >> 5) < cpt) {
+               /* use "cheap" math (add/subtract) instead
+                * of the more expensive div/mul method
+                */
+               cycles_remainder = cycles_elapsed;
+               while (cycles_remainder > cpt) {
+                       cycles_remainder -= cpt;
+               }
+       } else {
+               cycles_remainder = cycles_elapsed % cpt;
        }
-       mtctl(next_tick, 16);
+
+       /* Can we differentiate between "early CR16" (aka Scenario 1) and
+        * "long delay" (aka Scenario 3)? I don't think so.
+        *
+        * We expected timer_interrupt to be delivered at least a few hundred
+        * cycles after the IT fires. But it's arbitrary how much time passes
+        * before we call it "late". I've picked one second.
+        */
+/* aproximate HZ with shifts. Intended math is "(elapsed/clocktick) > HZ" */
+#if HZ == 1000
+       if (cycles_elapsed > (cpt << 10) )
+#elif HZ == 250
+       if (cycles_elapsed > (cpt << 8) )
+#elif HZ == 100
+       if (cycles_elapsed > (cpt << 7) )
+#else
+#warn WTF is HZ set to anyway?
+       if (cycles_elapsed > (HZ * cpt) )
+#endif
+       {
+               /* Scenario 3: very long delay?  bad in any case */
+               printk (KERN_CRIT "timer_interrupt(CPU %d): delayed!"
+                       " cycles %lX rem %lX "
+                       " next/now %lX/%lX\n",
+                       cpu,
+                       cycles_elapsed, cycles_remainder,
+                       next_tick, now );
+       }
+
+       /* convert from "division remainder" to "remainder of clock tick" */
+       cycles_remainder = cpt - cycles_remainder;
+
+       /* Determine when (in CR16 cycles) next IT interrupt will fire.
+        * We want IT to fire modulo clocktick even if we miss/skip some.
+        * But those interrupts don't in fact get delivered that regularly.
+        */
+       next_tick = now + cycles_remainder;
+
        cpu_data[cpu].it_value = next_tick;
 
-       while (nticks--) {
+       /* Skip one clocktick on purpose if we are likely to miss next_tick.
+        * We want to avoid the new next_tick being less than CR16.
+        * If that happened, itimer wouldn't fire until CR16 wrapped.
+        * We'll catch the tick we missed on the tick after that.
+        */
+       if (!(cycles_remainder >> 13))
+               next_tick += cpt;
+
+       /* Program the IT when to deliver the next interrupt. */
+        /* Only bottom 32-bits of next_tick are written to cr16.  */
+       mtctl(next_tick, 16);
+
+
+       /* Done mucking with unreliable delivery of interrupts.
+        * Go do system house keeping.
+        */
 #ifdef CONFIG_SMP
-               smp_do_timer(regs);
+       smp_do_timer(regs);
 #else
-               update_process_times(user_mode(regs));
+       update_process_times(user_mode(regs));
 #endif
-               if (cpu == 0) {
-                       write_seqlock(&xtime_lock);
-                       do_timer(1);
-                       write_sequnlock(&xtime_lock);
-               }
+       if (cpu == 0) {
+               write_seqlock(&xtime_lock);
+               do_timer(regs);
+               write_sequnlock(&xtime_lock);
        }
-    
+
        /* check soft power switch status */
        if (cpu == 0 && !atomic_read(&power_tasklet.count))
                tasklet_schedule(&power_tasklet);
@@ -106,14 +165,12 @@ unsigned long profile_pc(struct pt_regs *regs)
 EXPORT_SYMBOL(profile_pc);
 
 
-/*** converted from ia64 ***/
 /*
  * Return the number of micro-seconds that elapsed since the last
  * update to wall time (aka xtime).  The xtime_lock
  * must be at least read-locked when calling this routine.
  */
-static inline unsigned long
-gettimeoffset (void)
+static inline unsigned long gettimeoffset (void)
 {
 #ifndef CONFIG_SMP
        /*
@@ -121,21 +178,44 @@ gettimeoffset (void)
         *    Once parisc-linux learns the cr16 difference between processors,
         *    this could be made to work.
         */
-       long last_tick;
-       long elapsed_cycles;
-
-       /* it_value is the intended time of the next tick */
-       last_tick = cpu_data[smp_processor_id()].it_value;
-
-       /* Subtract one tick and account for possible difference between
-        * when we expected the tick and when it actually arrived.
-        * (aka wall vs real)
-        */
-       last_tick -= clocktick * (jiffies - wall_jiffies + 1);
-       elapsed_cycles = mfctl(16) - last_tick;
+       unsigned long now;
+       unsigned long prev_tick;
+       unsigned long next_tick;
+       unsigned long elapsed_cycles;
+       unsigned long usec;
+       unsigned long cpuid = smp_processor_id();
+       unsigned long cpt = clocktick;
+
+       next_tick = cpu_data[cpuid].it_value;
+       now = mfctl(16);        /* Read the hardware interval timer.  */
+
+       prev_tick = next_tick - cpt;
+
+       /* Assume Scenario 1: "now" is later than prev_tick.  */
+       elapsed_cycles = now - prev_tick;
+
+/* aproximate HZ with shifts. Intended math is "(elapsed/clocktick) > HZ" */
+#if HZ == 1000
+       if (elapsed_cycles > (cpt << 10) )
+#elif HZ == 250
+       if (elapsed_cycles > (cpt << 8) )
+#elif HZ == 100
+       if (elapsed_cycles > (cpt << 7) )
+#else
+#warn WTF is HZ set to anyway?
+       if (elapsed_cycles > (HZ * cpt) )
+#endif
+       {
+               /* Scenario 3: clock ticks are missing. */
+               printk (KERN_CRIT "gettimeoffset(CPU %ld): missing %ld ticks!"
+                       " cycles %lX prev/now/next %lX/%lX/%lX  clock %lX\n",
+                       cpuid, elapsed_cycles / cpt,
+                       elapsed_cycles, prev_tick, now, next_tick, cpt);
+       }
 
-       /* the precision of this math could be improved */
-       return elapsed_cycles / (PAGE0->mem_10msec / 10000);
+       /* FIXME: Can we improve the precision? Not with PAGE0. */
+       usec = (elapsed_cycles * 10000) / PAGE0->mem_10msec;
+       return usec;
 #else
        return 0;
 #endif
@@ -146,6 +226,7 @@ do_gettimeofday (struct timeval *tv)
 {
        unsigned long flags, seq, usec, sec;
 
+       /* Hold xtime_lock and adjust timeval.  */
        do {
                seq = read_seqbegin_irqsave(&xtime_lock, flags);
                usec = gettimeoffset();
@@ -153,25 +234,13 @@ do_gettimeofday (struct timeval *tv)
                usec += (xtime.tv_nsec / 1000);
        } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
 
-       if (unlikely(usec > LONG_MAX)) {
-               /* This can happen if the gettimeoffset adjustment is
-                * negative and xtime.tv_nsec is smaller than the
-                * adjustment */
-               printk(KERN_ERR "do_gettimeofday() spurious xtime.tv_nsec of %ld\n", usec);
-               usec += USEC_PER_SEC;
-               --sec;
-               /* This should never happen, it means the negative
-                * time adjustment was more than a second, so there's
-                * something seriously wrong */
-               BUG_ON(usec > LONG_MAX);
-       }
-
-
+       /* Move adjusted usec's into sec's.  */
        while (usec >= USEC_PER_SEC) {
                usec -= USEC_PER_SEC;
                ++sec;
        }
 
+       /* Return adjusted result.  */
        tv->tv_sec = sec;
        tv->tv_usec = usec;
 }
@@ -223,22 +292,23 @@ unsigned long long sched_clock(void)
 }
 
 
+void __init start_cpu_itimer(void)
+{
+       unsigned int cpu = smp_processor_id();
+       unsigned long next_tick = mfctl(16) + clocktick;
+
+       mtctl(next_tick, 16);           /* kick off Interval Timer (CR16) */
+
+       cpu_data[cpu].it_value = next_tick;
+}
+
 void __init time_init(void)
 {
-       unsigned long next_tick;
        static struct pdc_tod tod_data;
 
        clocktick = (100 * PAGE0->mem_10msec) / HZ;
-       halftick = clocktick / 2;
 
-       /* Setup clock interrupt timing */
-
-       next_tick = mfctl(16);
-       next_tick += clocktick;
-       cpu_data[smp_processor_id()].it_value = next_tick;
-
-       /* kick off Itimer (CR16) */
-       mtctl(next_tick, 16);
+       start_cpu_itimer();     /* get CPU 0 started */
 
        if(pdc_tod_read(&tod_data) == 0) {
                write_seqlock_irq(&xtime_lock);
index 77b28cb8aca6f1cecab831f219308c787869e729..65cd6ca32fed57b689f8a2dec3449dd620e3f098 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/timer.h>
+#include <linux/delay.h>
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/smp.h>
@@ -245,6 +246,15 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err)
                current->comm, current->pid, str, err);
        show_regs(regs);
 
+       if (in_interrupt())
+               panic("Fatal exception in interrupt");
+
+       if (panic_on_oops) {
+               printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
+               ssleep(5);
+               panic("Fatal exception");
+       }
+
        /* Wot's wrong wif bein' racy? */
        if (current->thread.flags & PARISC_KERNEL_DEATH) {
                printk(KERN_CRIT "%s() recursion detected.\n", __FUNCTION__);
index 25ad28d63e88398c057ddf259f262f49ea09a01f..0667f2b4f9775b13ab6fbc527884de52022bfa34 100644 (file)
 
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
-extern char _text;     /* start of kernel code, defined by linker */
 extern int  data_start;
-extern char _end;      /* end of BSS, defined by linker */
-extern char __init_begin, __init_end;
 
 #ifdef CONFIG_DISCONTIGMEM
 struct node_map_data node_data[MAX_NUMNODES] __read_mostly;
@@ -319,8 +316,8 @@ static void __init setup_bootmem(void)
 
        reserve_bootmem_node(NODE_DATA(0), 0UL,
                        (unsigned long)(PAGE0->mem_free + PDC_CONSOLE_IO_IODC_SIZE));
-       reserve_bootmem_node(NODE_DATA(0),__pa((unsigned long)&_text),
-                       (unsigned long)(&_end - &_text));
+       reserve_bootmem_node(NODE_DATA(0), __pa((unsigned long)_text),
+                       (unsigned long)(_end - _text));
        reserve_bootmem_node(NODE_DATA(0), (bootmap_start_pfn << PAGE_SHIFT),
                        ((bootmap_pfn - bootmap_start_pfn) << PAGE_SHIFT));
 
@@ -355,8 +352,8 @@ static void __init setup_bootmem(void)
 #endif
 
        data_resource.start =  virt_to_phys(&data_start);
-       data_resource.end = virt_to_phys(&_end)-1;
-       code_resource.start = virt_to_phys(&_text);
+       data_resource.end = virt_to_phys(_end) - 1;
+       code_resource.start = virt_to_phys(_text);
        code_resource.end = virt_to_phys(&data_start)-1;
 
        /* We don't know which region the kernel will be in, so try
@@ -385,12 +382,12 @@ void free_initmem(void)
         */
        local_irq_disable();
 
-       memset(&__init_begin, 0x00, 
-               (unsigned long)&__init_end - (unsigned long)&__init_begin);
+       memset(__init_begin, 0x00,
+               (unsigned long)__init_end - (unsigned long)__init_begin);
 
        flush_data_cache();
        asm volatile("sync" : : );
-       flush_icache_range((unsigned long)&__init_begin, (unsigned long)&__init_end);
+       flush_icache_range((unsigned long)__init_begin, (unsigned long)__init_end);
        asm volatile("sync" : : );
 
        local_irq_enable();
@@ -398,8 +395,8 @@ void free_initmem(void)
        
        /* align __init_begin and __init_end to page size,
           ignoring linker script where we might have tried to save RAM */
-       init_begin = PAGE_ALIGN((unsigned long)(&__init_begin));
-       init_end   = PAGE_ALIGN((unsigned long)(&__init_end));
+       init_begin = PAGE_ALIGN((unsigned long)(__init_begin));
+       init_end   = PAGE_ALIGN((unsigned long)(__init_end));
        for (addr = init_begin; addr < init_end; addr += PAGE_SIZE) {
                ClearPageReserved(virt_to_page(addr));
                init_page_count(virt_to_page(addr));
@@ -578,7 +575,7 @@ static void __init map_pages(unsigned long start_vaddr, unsigned long start_padd
        extern const unsigned long fault_vector_20;
        extern void * const linux_gateway_page;
 
-       ro_start = __pa((unsigned long)&_text);
+       ro_start = __pa((unsigned long)_text);
        ro_end   = __pa((unsigned long)&data_start);
        fv_addr  = __pa((unsigned long)&fault_vector_20) & PAGE_MASK;
        gw_addr  = __pa((unsigned long)&linux_gateway_page) & PAGE_MASK;
index 27384567a1d0a12e3719c7c9631c362e75e6636a..47a1d2ac941968086d089320ab86aaedb4f3c68f 100644 (file)
@@ -188,7 +188,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
 }
 EXPORT_SYMBOL(__ioremap);
 
-void iounmap(void __iomem *addr)
+void iounmap(const volatile void __iomem *addr)
 {
        if (addr > high_memory)
                return vfree((void *) (PAGE_MASK & (unsigned long __force) addr));
index a0dd1b0ee4838fc1b6f6b870354d67886c171fbe..8b6910465578b02cf8d00b9c9326f302d7ef5b5e 100644 (file)
@@ -338,10 +338,6 @@ config PPC_MULTIPLATFORM
          RS/6000 machine, an Apple machine, or a PReP, CHRP,
          Maple or Cell-based machine.
 
-config PPC_ISERIES
-       bool "IBM Legacy iSeries"
-       depends on PPC64
-
 config EMBEDDED6xx
        bool "Embedded 6xx/7xx/7xxx-based board"
        depends on PPC32 && (BROKEN||BROKEN_ON_SMP)
@@ -355,6 +351,16 @@ config APUS
          <http://linux-apus.sourceforge.net/>.
 endchoice
 
+config QUICC_ENGINE
+       bool
+       depends on PPC_MPC836x || PPC_MPC832x
+       default y
+       help
+         The QUICC Engine (QE) is a new generation of communications
+         coprocessors on Freescale embedded CPUs (akin to CPM in older chips).
+         Selecting this option means that you wish to build a kernel
+         for a machine with a QE coprocessor.
+
 config PPC_PSERIES
        depends on PPC_MULTIPLATFORM && PPC64
        bool "IBM pSeries & new (POWER5-based) iSeries"
@@ -365,6 +371,10 @@ config PPC_PSERIES
        select PPC_UDBG_16550
        default y
 
+config PPC_ISERIES
+       bool "IBM Legacy iSeries"
+       depends on PPC_MULTIPLATFORM && PPC64
+
 config PPC_CHRP
        bool "Common Hardware Reference Platform (CHRP) based machines"
        depends on PPC_MULTIPLATFORM && PPC32
@@ -594,6 +604,7 @@ endmenu
 
 source arch/powerpc/platforms/embedded6xx/Kconfig
 source arch/powerpc/platforms/4xx/Kconfig
+source arch/powerpc/platforms/82xx/Kconfig
 source arch/powerpc/platforms/83xx/Kconfig
 source arch/powerpc/platforms/85xx/Kconfig
 source arch/powerpc/platforms/86xx/Kconfig
@@ -1002,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
@@ -1013,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.
 
@@ -1058,6 +1069,8 @@ source "fs/Kconfig"
 
 # XXX source "arch/ppc/8260_io/Kconfig"
 
+source "arch/powerpc/sysdev/qe_lib/Kconfig"
+
 source "arch/powerpc/platforms/iseries/Kconfig"
 
 source "lib/Kconfig"
@@ -1069,7 +1082,7 @@ source "arch/powerpc/oprofile/Kconfig"
 
 config KPROBES
        bool "Kprobes (EXPERIMENTAL)"
-       depends on PPC64 && EXPERIMENTAL && MODULES
+       depends on PPC64 && KALLSYMS && EXPERIMENTAL && MODULES
        help
          Kprobes allows you to trap at almost any kernel address and
          execute a callback function.  register_kprobe() establishes
index 01667d1d571dbdee4636760d924b98604404b8e0..a00fe7236555676aa1abdabafc4f355456e335d3 100644 (file)
@@ -20,6 +20,7 @@ CROSS32_COMPILE ?=
 CROSS32CC              := $(CROSS32_COMPILE)gcc
 CROSS32AS              := $(CROSS32_COMPILE)as
 CROSS32LD              := $(CROSS32_COMPILE)ld
+CROSS32AR              := $(CROSS32_COMPILE)ar
 CROSS32OBJCOPY         := $(CROSS32_COMPILE)objcopy
 
 ifeq ($(HAS_BIARCH),y)
@@ -28,10 +29,11 @@ CROSS32CC   := $(CC) -m32
 CROSS32AS      := $(AS) -a32
 CROSS32LD      := $(LD) -m elf32ppc
 CROSS32OBJCOPY := $(OBJCOPY)
+CROSS32AR      := $(AR)
 endif
 endif
 
-export CROSS32CC CROSS32AS CROSS32LD CROSS32OBJCOPY
+export CROSS32CC CROSS32AS CROSS32LD CROSS32AR CROSS32OBJCOPY
 
 KBUILD_DEFCONFIG := $(shell uname -m)_defconfig
 
@@ -146,7 +148,7 @@ all: $(KBUILD_IMAGE)
 
 CPPFLAGS_vmlinux.lds   := -Upowerpc
 
-BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm uImage vmlinux.bin
+BOOT_TARGETS = zImage zImage.initrd uImage
 
 PHONY += $(BOOT_TARGETS)
 
index e73774136b5586dd547a9e048c79eddb8d70ad23..003520b56303e2f4e275d436827a6a6152c8f3a4 100644 (file)
 #      CROSS32_COMPILE is setup as a prefix just like CROSS_COMPILE
 #      in the toplevel makefile.
 
+all: $(obj)/zImage
 
 HOSTCC         := gcc
 BOOTCFLAGS     := $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem \
                   $(shell $(CROSS32CC) -print-file-name=include) -fPIC
 BOOTAFLAGS     := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc
-OBJCOPYFLAGS    := contents,alloc,load,readonly,data
-OBJCOPY_COFF_ARGS := -O aixcoff-rs6000 --set-start 0x500000
-OBJCOPY_MIB_ARGS  := -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment
+
+ifeq ($(call cc-option-yn, -fstack-protector),y)
+BOOTCFLAGS     += -fno-stack-protector
+endif
+
+BOOTCFLAGS     += -I$(obj) -I$(srctree)/$(obj)
 
 zlib       := inffast.c inflate.c inftrees.c
 zlibheader := inffast.h inffixed.h inflate.h inftrees.h infutil.h
 zliblinuxheader := zlib.h zconf.h zutil.h
 
-$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
-#$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h)
+$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) \
+               $(addprefix $(obj)/,$(zlibheader))
+
+src-wlib := string.S stdio.c main.c div64.S $(zlib)
+src-plat := of.c
+src-boot := crt0.S $(src-wlib) $(src-plat) empty.c
 
-src-boot-$(CONFIG_PPC_MULTIPLATFORM) := of.c
-src-boot := crt0.S string.S stdio.c main.c div64.S $(src-boot-y)
-src-boot += $(zlib)
 src-boot := $(addprefix $(obj)/, $(src-boot))
 obj-boot := $(addsuffix .o, $(basename $(src-boot)))
-
-ifeq ($(call cc-option-yn, -fstack-protector),y)
-BOOTCFLAGS     += -fno-stack-protector
-endif
-
-BOOTCFLAGS     += -I$(obj) -I$(srctree)/$(obj)
+obj-wlib := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-wlib))))
+obj-plat := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-plat))))
 
 quiet_cmd_copy_zlib = COPY    $@
       cmd_copy_zlib = sed "s@__attribute_used__@@;s@<linux/\([^>]\+\).*@\"\1\"@" $< > $@
@@ -66,8 +67,14 @@ $(addprefix $(obj)/,$(zlibheader)): $(obj)/%: $(srctree)/lib/zlib_inflate/%
 $(addprefix $(obj)/,$(zliblinuxheader)): $(obj)/%: $(srctree)/include/linux/%
        $(call cmd,copy_zliblinuxheader)
 
-clean-files := $(zlib) $(zlibheader) $(zliblinuxheader)
+$(obj)/empty.c:
+       @touch $@
+
+$(obj)/zImage.lds $(obj)/zImage.coff.lds: $(obj)/%: $(srctree)/$(src)/%.S
+       @cp $< $@
 
+clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \
+               $(obj)/empty.c
 
 quiet_cmd_bootcc = BOOTCC  $@
       cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $<
@@ -75,146 +82,97 @@ quiet_cmd_bootcc = BOOTCC  $@
 quiet_cmd_bootas = BOOTAS  $@
       cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $<
 
-quiet_cmd_bootld = BOOTLD  $@
-      cmd_bootld = $(CROSS32LD) -T $(srctree)/$(src)/$(3) -o $@ $(2)
+quiet_cmd_bootar = BOOTAR  $@
+      cmd_bootar = $(CROSS32AR) -cr $@.$$$$ $^; mv $@.$$$$ $@
 
 $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c
        $(call if_changed_dep,bootcc)
 $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S
        $(call if_changed_dep,bootas)
 
-#-----------------------------------------------------------
-# ELF sections within the zImage bootloader/wrapper
-#-----------------------------------------------------------
-required := vmlinux.strip
-initrd   := initrd
+$(obj)/wrapper.a: $(obj-wlib)
+       $(call cmd,bootar)
 
-obj-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.o, $(section)))
-src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section)))
-gz-sec  = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section)))
+hostprogs-y    := addnote addRamDisk hack-coff
 
-hostprogs-y            := addnote addRamDisk hack-coff
+extra-y                := $(obj)/crt0.o $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \
+                  $(obj)/zImage.lds $(obj)/zImage.coff.lds
 
-targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd \
-          zImage.coff zImage.initrd.coff miboot.image miboot.initrd.image \
-          $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \
-          $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \
-          $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \
-          vmlinux.initrd dummy.o
-extra-y                        := initrd.o
+wrapper                :=$(srctree)/$(src)/wrapper
+wrapperbits    := $(extra-y) $(addprefix $(obj)/,addnote hack-coff)
 
-quiet_cmd_ramdisk = RAMDISK $@
-      cmd_ramdisk = $(obj)/addRamDisk $(obj)/ramdisk.image.gz $< $@
+#############
+# Bits for building various flavours of zImage
 
-quiet_cmd_stripvm = STRIP   $@
-      cmd_stripvm = $(STRIP) -s -R .comment $< -o $@
+ifneq ($(CROSS32_COMPILE),)
+CROSSWRAP := -C $(CROSS32_COMPILE)
+else
+ifneq ($(CROSS_COMPILE),)
+CROSSWRAP := -C $(CROSS_COMPILE)
+endif
+endif
 
-vmlinux.strip: vmlinux
-       $(call if_changed,stripvm)
-$(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz
-       $(call if_changed,ramdisk)
+quiet_cmd_wrap = WRAP    $@
+      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
 
-quiet_cmd_addsection = ADDSEC  $@
-      cmd_addsection = $(CROSS32OBJCOPY) $@ \
-               --add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(patsubst %.o,%.gz, $@) \
-               --set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(OBJCOPYFLAGS)
+$(obj)/zImage.chrp: vmlinux $(wrapperbits)
+       $(call cmd,wrap,chrp)
 
-quiet_cmd_addnote = ADDNOTE $@
-      cmd_addnote = $(obj)/addnote $@
+$(obj)/zImage.initrd.chrp: vmlinux $(wrapperbits)
+       $(call cmd,wrap_initrd,chrp)
 
-quiet_cmd_gen-miboot = GEN     $@
-      cmd_gen-miboot = $(OBJCOPY) $(OBJCOPY_MIB_ARGS) \
-                      --add-section=$1=$(word 2, $^) $< $@
+$(obj)/zImage.pseries: vmlinux $(wrapperbits)
+       $(call cmd,wrap,pseries)
 
-quiet_cmd_gencoff = COFF    $@
-      cmd_gencoff = $(OBJCOPY) $(OBJCOPY_COFF_ARGS) $@ && \
-                   $(obj)/hack-coff $@
+$(obj)/zImage.initrd.pseries: vmlinux $(wrapperbits)
+       $(call cmd,wrap_initrd,pseries)
 
-$(call gz-sec, $(required)): $(obj)/kernel-%.gz: %
-       $(call if_changed,gzip)
+$(obj)/zImage.pmac: vmlinux $(wrapperbits)
+       $(call cmd,wrap,pmac)
 
-$(obj)/kernel-initrd.gz: $(obj)/ramdisk.image.gz
-       cp -f $(obj)/ramdisk.image.gz $@
+$(obj)/zImage.initrd.pmac: vmlinux $(wrapperbits)
+       $(call cmd,wrap_initrd,pmac)
 
-$(call src-sec, $(required) $(initrd)): $(obj)/kernel-%.c: $(obj)/kernel-%.gz
-       @touch $@
+$(obj)/zImage.coff: vmlinux $(wrapperbits)
+       $(call cmd,wrap,pmaccoff)
 
-$(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c
-       $(call if_changed_dep,bootcc)
-       $(call cmd,addsection)
+$(obj)/zImage.initrd.coff: vmlinux $(wrapperbits)
+       $(call cmd,wrap_initrd,pmaccoff)
+
+$(obj)/zImage.miboot: vmlinux $(wrapperbits)
+       $(call cmd,wrap,miboot)
 
-$(obj)/zImage.vmode $(obj)/zImage.coff: obj-boot += $(call obj-sec, $(required))
-$(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) $(srctree)/$(src)/zImage.lds
-       $(call cmd,bootld,$(obj-boot),zImage.lds)
+$(obj)/zImage.initrd.miboot: vmlinux $(wrapperbits)
+       $(call cmd,wrap_initrd,miboot)
 
-$(obj)/zImage.initrd.vmode $(obj)/zImage.initrd.coff: obj-boot += $(call obj-sec, $(required) $(initrd))
-$(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(srctree)/$(src)/zImage.lds
-       $(call cmd,bootld,$(obj-boot),zImage.lds)
+$(obj)/uImage: vmlinux $(wrapperbits)
+       $(call cmd,wrap,uboot)
+
+image-$(CONFIG_PPC_PSERIES)    += zImage.pseries
+image-$(CONFIG_PPC_MAPLE)      += zImage.pseries
+image-$(CONFIG_PPC_CELL)       += zImage.pseries
+image-$(CONFIG_PPC_CHRP)       += zImage.chrp
+image-$(CONFIG_PPC_PMAC)       += zImage.pmac
+image-$(CONFIG_DEFAULT_UIMAGE) += uImage
 
 # For 32-bit powermacs, build the COFF and miboot images
 # as well as the ELF images.
-coffimage-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/zImage.coff
-coffrdimg-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/zImage.initrd.coff
-mibootimg-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/miboot.image
-mibrdimg-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32)  := $(obj)/miboot.initrd.image
-
-$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote $(coffimage-y-y) \
-                       $(mibootimg-y-y)
-       @cp -f $< $@
-       $(call if_changed,addnote)
-
-$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote \
-                       $(coffrdimg-y-y) $(mibrdimg-y-y)
-       @cp -f $< $@
-       $(call if_changed,addnote)
-
-$(obj)/zImage.coff: $(call obj-sec, $(required)) $(obj-boot) \
-                       $(srctree)/$(src)/zImage.coff.lds $(obj)/hack-coff
-       $(call cmd,bootld,$(obj-boot),zImage.coff.lds)
-       $(call cmd,gencoff)
-
-$(obj)/zImage.initrd.coff: $(call obj-sec, $(required) $(initrd)) $(obj-boot) \
-                          $(srctree)/$(src)/zImage.coff.lds $(obj)/hack-coff
-       $(call cmd,bootld,$(obj-boot),zImage.coff.lds)
-       $(call cmd,gencoff)
-
-$(obj)/miboot.image: $(obj)/dummy.o $(obj)/vmlinux.gz
-       $(call cmd,gen-miboot,image)
-
-$(obj)/miboot.initrd.image: $(obj)/miboot.image $(images)/ramdisk.image.gz
-       $(call cmd,gen-miboot,initrd)
-
-#-----------------------------------------------------------
-# build u-boot images
-#-----------------------------------------------------------
-quiet_cmd_mygzip = GZIP $@
-cmd_mygzip = gzip -f -9 < $< > $@.$$$$ && mv $@.$$$$ $@
-
-quiet_cmd_objbin = OBJCOPY $@
-      cmd_objbin = $(OBJCOPY) -O binary $< $@
-
-quiet_cmd_uimage = UIMAGE $@
-      cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A ppc -O linux -T kernel \
-               -C gzip -a 00000000 -e 00000000 -n 'Linux-$(KERNELRELEASE)' \
-               -d $< $@
-
-MKIMAGE                := $(srctree)/scripts/mkuboot.sh
-targets                += uImage
-extra-y                += vmlinux.bin vmlinux.gz
-
-$(obj)/vmlinux.bin: vmlinux FORCE
-       $(call if_changed,objbin)
-
-$(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE
-       $(call if_changed,mygzip)
-
-$(obj)/uImage: $(obj)/vmlinux.gz
-       $(Q)rm -f $@
-       $(call cmd,uimage)
-       @echo -n '  Image: $@ '
-       @if [ -f $@ ]; then echo 'is ready' ; else echo 'not made'; fi
-
-install: $(CONFIGURE) $(BOOTIMAGE)
-       sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" "$(BOOTIMAGE)"
-
-clean-files += $(addprefix $(objtree)/, $(obj-boot) vmlinux.strip)
+ifeq ($(CONFIG_PPC32),y)
+image-$(CONFIG_PPC_PMAC)       += zImage.coff zImage.miboot
+endif
+
+initrd-y := $(patsubst zImage%, zImage.initrd%, $(image-y))
+
+$(obj)/zImage:         $(addprefix $(obj)/, $(image-y))
+       @rm -f $@; ln $< $@
+$(obj)/zImage.initrd:  $(addprefix $(obj)/, $(initrd-y))
+       @rm -f $@; ln $< $@
+
+install: $(CONFIGURE) $(image-y)
+       sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" $<
+
+clean-files += $(addprefix $(objtree)/, $(obj-boot) vmlinux.strip.gz)
+clean-files += $(addprefix $(objtree)/, $(obj-boot) vmlinux.bin.gz)
diff --git a/arch/powerpc/boot/dts/mpc8272ads.dts b/arch/powerpc/boot/dts/mpc8272ads.dts
new file mode 100644 (file)
index 0000000..34efdd0
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * MPC8272 ADS Device Tree Source
+ *
+ * Copyright 2005 Freescale Semiconductor Inc.
+ *
+ * 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.
+ */
+
+/ {
+       model = "MPC8272ADS";
+       compatible = "MPC8260ADS";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       linux,phandle = <100>;
+
+       cpus {
+               #cpus = <1>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               linux,phandle = <200>;
+
+               PowerPC,8272@0 {
+                       device_type = "cpu";
+                       reg = <0>;
+                       d-cache-line-size = <20>;       // 32 bytes
+                       i-cache-line-size = <20>;       // 32 bytes
+                       d-cache-size = <4000>;          // L1, 16K
+                       i-cache-size = <4000>;          // L1, 16K
+                       timebase-frequency = <0>;
+                       bus-frequency = <0>;
+                       clock-frequency = <0>;
+                       32-bit;
+                       linux,phandle = <201>;
+                       linux,boot-cpu;
+               };
+       };
+
+       interrupt-controller@f8200000 {
+               linux,phandle = <f8200000>;
+               #address-cells = <0>;
+               #interrupt-cells = <2>;
+               interrupt-controller;
+               reg = <f8200000 f8200004>;
+               built-in;
+               device_type = "pci-pic";
+       };
+       memory {
+               device_type = "memory";
+               linux,phandle = <300>;
+               reg = <00000000 4000000 f4500000 00000020>;
+       };
+
+       soc8272@f0000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               #interrupt-cells = <2>;
+               device_type = "soc";
+               ranges = < 0 0 2 00000000 f0000000 00053000>;
+               reg = <f0000000 0>;
+
+               mdio@0 {
+                       device_type = "mdio";
+                       compatible = "fs_enet";
+                       reg = <0 0>;
+                       linux,phandle = <24520>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ethernet-phy@0 {
+                               linux,phandle = <2452000>;
+                               interrupt-parent = <10c00>;
+                               interrupts = <19 1>;
+                               reg = <0>;
+                               bitbang = [ 12 12 13 02 02 01 ];
+                               device_type = "ethernet-phy";
+                       };
+                       ethernet-phy@1 {
+                               linux,phandle = <2452001>;
+                               interrupt-parent = <10c00>;
+                               interrupts = <19 1>;
+                               bitbang = [ 12 12 13 02 02 01 ];
+                               reg = <3>;
+                               device_type = "ethernet-phy";
+                       };
+               };
+
+               ethernet@24000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       device_type = "network";
+                       device-id = <2>;
+                       compatible = "fs_enet";
+                       model = "FCC";
+                       reg = <11300 20 8400 100 11380 30>;
+                       mac-address = [ 00 11 2F 99 43 54 ];
+                       interrupts = <20 2>;
+                       interrupt-parent = <10c00>;
+                       phy-handle = <2452000>;
+                       rx-clock = <13>;
+                       tx-clock = <12>;
+               };
+
+               ethernet@25000 {
+                       device_type = "network";
+                       device-id = <3>;
+                       compatible = "fs_enet";
+                       model = "FCC";
+                       reg = <11320 20 8500 100 113b0 30>;
+                       mac-address = [ 00 11 2F 99 44 54 ];
+                       interrupts = <21 2>;
+                       interrupt-parent = <10c00>;
+                       phy-handle = <2452001>;
+                       rx-clock = <17>;
+                       tx-clock = <18>;
+               };
+
+               cpm@f0000000 {
+                       linux,phandle = <f0000000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       #interrupt-cells = <2>;
+                       device_type = "cpm";
+                       model = "CPM2";
+                       ranges = <00000000 00000000 3ffff>;
+                       reg = <10d80 3280>;
+                       command-proc = <119c0>;
+                       brg-frequency = <17D7840>;
+                       cpm_clk = <BEBC200>;
+
+                       scc@11a00 {
+                               device_type = "serial";
+                               compatible = "cpm_uart";
+                               model = "SCC";
+                               device-id = <2>;
+                               reg = <11a00 20 8000 100>;
+                               current-speed = <1c200>;
+                               interrupts = <28 2>;
+                               interrupt-parent = <10c00>;
+                               clock-setup = <0 00ffffff>;
+                               rx-clock = <1>;
+                               tx-clock = <1>;
+                       };
+
+                       scc@11a60 {
+                               device_type = "serial";
+                               compatible = "cpm_uart";
+                               model = "SCC";
+                               device-id = <5>;
+                               reg = <11a60 20 8300 100>;
+                               current-speed = <1c200>;
+                               interrupts = <2b 2>;
+                               interrupt-parent = <10c00>;
+                               clock-setup = <1b ffffff00>;
+                               rx-clock = <4>;
+                               tx-clock = <4>;
+                       };
+
+               };
+               interrupt-controller@10c00 {
+                       linux,phandle = <10c00>;
+                       #address-cells = <0>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       reg = <10c00 80>;
+                       built-in;
+                       device_type = "cpm-pic";
+                      compatible = "CPM2";
+               };
+               pci@0500 {
+                       linux,phandle = <0500>;
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       compatible = "8272";
+                       device_type = "pci";
+                       reg = <10430 4dc>;
+                       clock-frequency = <3f940aa>;
+                       interrupt-map-mask = <f800 0 0 7>;
+                       interrupt-map = <
+
+                                       /* IDSEL 0x16 */
+                                        b000 0 0 1 f8200000 40 0
+                                        b000 0 0 2 f8200000 41 0
+                                        b000 0 0 3 f8200000 42 0
+                                        b000 0 0 4 f8200000 43 0
+
+                                       /* IDSEL 0x17 */
+                                        b800 0 0 1 f8200000 43 0
+                                        b800 0 0 2 f8200000 40 0
+                                        b800 0 0 3 f8200000 41 0
+                                        b800 0 0 4 f8200000 42 0
+
+                                       /* IDSEL 0x18 */
+                                        c000 0 0 1 f8200000 42 0
+                                        c000 0 0 2 f8200000 43 0
+                                        c000 0 0 3 f8200000 40 0
+                                        c000 0 0 4 f8200000 41 0>;
+                       interrupt-parent = <10c00>;
+                       interrupts = <14 3>;
+                       bus-range = <0 0>;
+                       ranges = <02000000 0 80000000 80000000 0 40000000
+                                 01000000 0 00000000 f6000000 0 02000000>;
+               };
+
+/* May need to remove if on a part without crypto engine */
+               crypto@30000 {
+                       device_type = "crypto";
+                       model = "SEC2";
+                       compatible = "talitos";
+                       reg = <30000 10000>;
+                       interrupts = <b 0>;
+                       interrupt-parent = <10c00>;
+                       num-channels = <4>;
+                       channel-fifo-len = <18>;
+                       exec-units-mask = <0000007e>;
+/* desc mask is for rev1.x, we need runtime fixup for >=2.x */
+                       descriptor-types-mask = <01010ebf>;
+               };
+
+       };
+};
diff --git a/arch/powerpc/boot/dts/mpc8360emds.dts b/arch/powerpc/boot/dts/mpc8360emds.dts
new file mode 100644 (file)
index 0000000..9022192
--- /dev/null
@@ -0,0 +1,375 @@
+/*
+ * MPC8360E EMDS Device Tree Source
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * 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.
+ */
+
+
+/*
+/memreserve/   00000000 1000000;
+*/
+
+/ {
+       model = "MPC8360EPB";
+       compatible = "MPC83xx";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       linux,phandle = <100>;
+
+       cpus {
+               #cpus = <1>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               linux,phandle = <200>;
+
+               PowerPC,8360@0 {
+                       device_type = "cpu";
+                       reg = <0>;
+                       d-cache-line-size = <20>;       // 32 bytes
+                       i-cache-line-size = <20>;       // 32 bytes
+                       d-cache-size = <8000>;          // L1, 32K
+                       i-cache-size = <8000>;          // L1, 32K
+                       timebase-frequency = <3EF1480>;
+                       bus-frequency = <FBC5200>;
+                       clock-frequency = <1F78A400>;
+                       32-bit;
+                       linux,phandle = <201>;
+                       linux,boot-cpu;
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               linux,phandle = <300>;
+               reg = <00000000 10000000>;
+       };
+
+       bcsr@f8000000 {
+               device_type = "board-control";
+               reg = <f8000000 8000>;
+       };
+
+       soc8360@e0000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               #interrupt-cells = <2>;
+               device_type = "soc";
+               ranges = <0 e0000000 00100000>;
+               reg = <e0000000 00000200>;
+               bus-frequency = <FBC5200>;
+
+               wdt@200 {
+                       device_type = "watchdog";
+                       compatible = "mpc83xx_wdt";
+                       reg = <200 100>;
+               };
+
+               i2c@3000 {
+                       device_type = "i2c";
+                       compatible = "fsl-i2c";
+                       reg = <3000 100>;
+                       interrupts = <e 8>;
+                       interrupt-parent = <700>;
+                       dfsrr;
+               };
+
+               i2c@3100 {
+                       device_type = "i2c";
+                       compatible = "fsl-i2c";
+                       reg = <3100 100>;
+                       interrupts = <f 8>;
+                       interrupt-parent = <700>;
+                       dfsrr;
+               };
+
+               serial@4500 {
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <4500 100>;
+                       clock-frequency = <FBC5200>;
+                       interrupts = <9 8>;
+                       interrupt-parent = <700>;
+               };
+
+               serial@4600 {
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <4600 100>;
+                       clock-frequency = <FBC5200>;
+                       interrupts = <a 8>;
+                       interrupt-parent = <700>;
+               };
+
+               crypto@30000 {
+                       device_type = "crypto";
+                       model = "SEC2";
+                       compatible = "talitos";
+                       reg = <30000 10000>;
+                       interrupts = <b 8>;
+                       interrupt-parent = <700>;
+                       num-channels = <4>;
+                       channel-fifo-len = <18>;
+                       exec-units-mask = <0000007e>;
+                       /* desc mask is for rev1.x, we need runtime fixup for >=2.x */
+                       descriptor-types-mask = <01010ebf>;
+               };
+
+               pci@8500 {
+                       linux,phandle = <8500>;
+                       interrupt-map-mask = <f800 0 0 7>;
+                       interrupt-map = <
+
+                                       /* IDSEL 0x11 AD17 */
+                                        8800 0 0 1 700 14 8
+                                        8800 0 0 2 700 15 8
+                                        8800 0 0 3 700 16 8
+                                        8800 0 0 4 700 17 8
+
+                                       /* IDSEL 0x12 AD18 */
+                                        9000 0 0 1 700 16 8
+                                        9000 0 0 2 700 17 8
+                                        9000 0 0 3 700 14 8
+                                        9000 0 0 4 700 15 8
+
+                                       /* IDSEL 0x13 AD19 */
+                                        9800 0 0 1 700 17 8
+                                        9800 0 0 2 700 14 8
+                                        9800 0 0 3 700 15 8
+                                        9800 0 0 4 700 16 8
+
+                                       /* IDSEL 0x15 AD21*/
+                                        a800 0 0 1 700 14 8
+                                        a800 0 0 2 700 15 8
+                                        a800 0 0 3 700 16 8
+                                        a800 0 0 4 700 17 8
+
+                                       /* IDSEL 0x16 AD22*/
+                                        b000 0 0 1 700 17 8
+                                        b000 0 0 2 700 14 8
+                                        b000 0 0 3 700 15 8
+                                        b000 0 0 4 700 16 8
+
+                                       /* IDSEL 0x17 AD23*/
+                                        b800 0 0 1 700 16 8
+                                        b800 0 0 2 700 17 8
+                                        b800 0 0 3 700 14 8
+                                        b800 0 0 4 700 15 8
+
+                                       /* IDSEL 0x18 AD24*/
+                                        c000 0 0 1 700 15 8
+                                        c000 0 0 2 700 16 8
+                                        c000 0 0 3 700 17 8
+                                        c000 0 0 4 700 14 8>;
+                       interrupt-parent = <700>;
+                       interrupts = <42 8>;
+                       bus-range = <0 0>;
+                       ranges = <02000000 0 a0000000 a0000000 0 10000000
+                                 42000000 0 80000000 80000000 0 10000000
+                                 01000000 0 00000000 e2000000 0 00100000>;
+                       clock-frequency = <3f940aa>;
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       reg = <8500 100>;
+                       compatible = "83xx";
+                       device_type = "pci";
+               };
+
+               pic@700 {
+                       linux,phandle = <700>;
+                       interrupt-controller;
+                       #address-cells = <0>;
+                       #interrupt-cells = <2>;
+                       reg = <700 100>;
+                       built-in;
+                       device_type = "ipic";
+               };
+
+               par_io@1400 {
+                       reg = <1400 100>;
+                       device_type = "par_io";
+                       num-ports = <7>;
+
+                       ucc_pin@01 {
+                               linux,phandle = <140001>;
+                               pio-map = <
+                       /* port  pin  dir  open_drain  assignment  has_irq */
+                                       0  3  1  0  1  0        /* TxD0 */
+                                       0  4  1  0  1  0        /* TxD1 */
+                                       0  5  1  0  1  0        /* TxD2 */
+                                       0  6  1  0  1  0        /* TxD3 */
+                                       1  6  1  0  3  0        /* TxD4 */
+                                       1  7  1  0  1  0        /* TxD5 */
+                                       1  9  1  0  2  0        /* TxD6 */
+                                       1  a  1  0  2  0        /* TxD7 */
+                                       0  9  2  0  1  0        /* RxD0 */
+                                       0  a  2  0  1  0        /* RxD1 */
+                                       0  b  2  0  1  0        /* RxD2 */
+                                       0  c  2  0  1  0        /* RxD3 */
+                                       0  d  2  0  1  0        /* RxD4 */
+                                       1  1  2  0  2  0        /* RxD5 */
+                                       1  0  2  0  2  0        /* RxD6 */
+                                       1  4  2  0  2  0        /* RxD7 */
+                                       0  7  1  0  1  0        /* TX_EN */
+                                       0  8  1  0  1  0        /* TX_ER */
+                                       0  f  2  0  1  0        /* RX_DV */
+                                       0  10 2  0  1  0        /* RX_ER */
+                                       0  0  2  0  1  0        /* RX_CLK */
+                                       2  9  1  0  3  0        /* GTX_CLK - CLK10 */
+                                       2  8  2  0  1  0>;      /* GTX125 - CLK9 */
+                       };
+                       ucc_pin@02 {
+                               linux,phandle = <140002>;
+                               pio-map = <
+                       /* port  pin  dir  open_drain  assignment  has_irq */
+                                       0  11 1  0  1  0   /* TxD0 */
+                                       0  12 1  0  1  0   /* TxD1 */
+                                       0  13 1  0  1  0   /* TxD2 */
+                                       0  14 1  0  1  0   /* TxD3 */
+                                       1  2  1  0  1  0   /* TxD4 */
+                                       1  3  1  0  2  0   /* TxD5 */
+                                       1  5  1  0  3  0   /* TxD6 */
+                                       1  8  1  0  3  0   /* TxD7 */
+                                       0  17 2  0  1  0   /* RxD0 */
+                                       0  18 2  0  1  0   /* RxD1 */
+                                       0  19 2  0  1  0   /* RxD2 */
+                                       0  1a 2  0  1  0   /* RxD3 */
+                                       0  1b 2  0  1  0   /* RxD4 */
+                                       1  c  2  0  2  0   /* RxD5 */
+                                       1  d  2  0  3  0   /* RxD6 */
+                                       1  b  2  0  2  0   /* RxD7 */
+                                       0  15 1  0  1  0   /* TX_EN */
+                                       0  16 1  0  1  0   /* TX_ER */
+                                       0  1d 2  0  1  0   /* RX_DV */
+                                       0  1e 2  0  1  0   /* RX_ER */
+                                       0  1f 2  0  1  0   /* RX_CLK */
+                                       2  2  1  0  2  0   /* GTX_CLK - CLK10 */
+                                       2  3  2  0  1  0   /* GTX125 - CLK4 */
+                                       0  1  3  0  2  0   /* MDIO */
+                                       0  2  1  0  1  0>; /* MDC */
+                       };
+
+               };
+       };
+
+       qe@e0100000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               device_type = "qe";
+               model = "QE";
+               ranges = <0 e0100000 00100000>;
+               reg = <e0100000 480>;
+               brg-frequency = <0>;
+               bus-frequency = <179A7B00>;
+
+               muram@10000 {
+                       device_type = "muram";
+                       ranges = <0 00010000 0000c000>;
+
+                       data-only@0{
+                               reg = <0 c000>;
+                       };
+               };
+
+               spi@4c0 {
+                       device_type = "spi";
+                       compatible = "fsl_spi";
+                       reg = <4c0 40>;
+                       interrupts = <2>;
+                       interrupt-parent = <80>;
+                       mode = "cpu";
+               };
+
+               spi@500 {
+                       device_type = "spi";
+                       compatible = "fsl_spi";
+                       reg = <500 40>;
+                       interrupts = <1>;
+                       interrupt-parent = <80>;
+                       mode = "cpu";
+               };
+
+               usb@6c0 {
+                       device_type = "usb";
+                       compatible = "qe_udc";
+                       reg = <6c0 40 8B00 100>;
+                       interrupts = <b>;
+                       interrupt-parent = <80>;
+                       mode = "slave";
+               };
+
+               ucc@2000 {
+                       device_type = "network";
+                       compatible = "ucc_geth";
+                       model = "UCC";
+                       device-id = <1>;
+                       reg = <2000 200>;
+                       interrupts = <20>;
+                       interrupt-parent = <80>;
+                       mac-address = [ 00 04 9f 00 23 23 ];
+                       rx-clock = <0>;
+                       tx-clock = <19>;
+                       phy-handle = <212000>;
+                       pio-handle = <140001>;
+               };
+
+               ucc@3000 {
+                       device_type = "network";
+                       compatible = "ucc_geth";
+                       model = "UCC";
+                       device-id = <2>;
+                       reg = <3000 200>;
+                       interrupts = <21>;
+                       interrupt-parent = <80>;
+                       mac-address = [ 00 11 22 33 44 55 ];
+                       rx-clock = <0>;
+                       tx-clock = <14>;
+                       phy-handle = <212001>;
+                       pio-handle = <140002>;
+               };
+
+               mdio@2120 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <2120 18>;
+                       device_type = "mdio";
+                       compatible = "ucc_geth_phy";
+
+                       ethernet-phy@00 {
+                               linux,phandle = <212000>;
+                               interrupt-parent = <700>;
+                               interrupts = <11 2>;
+                               reg = <0>;
+                               device_type = "ethernet-phy";
+                               interface = <6>; //ENET_1000_GMII
+                       };
+                       ethernet-phy@01 {
+                               linux,phandle = <212001>;
+                               interrupt-parent = <700>;
+                               interrupts = <12 2>;
+                               reg = <1>;
+                               device_type = "ethernet-phy";
+                               interface = <6>;
+                       };
+               };
+
+               qeic@80 {
+                       linux,phandle = <80>;
+                       interrupt-controller;
+                       device_type = "qeic";
+                       #address-cells = <0>;
+                       #interrupt-cells = <1>;
+                       reg = <80 80>;
+                       built-in;
+                       big-endian;
+                       interrupts = <20 8 21 8>; //high:32 low:33
+                       interrupt-parent = <700>;
+               };
+
+       };
+};
diff --git a/arch/powerpc/boot/dts/mpc8560ads.dts b/arch/powerpc/boot/dts/mpc8560ads.dts
new file mode 100644 (file)
index 0000000..2b16848
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+ * MPC8560 ADS Device Tree Source
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * 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.
+ */
+
+
+/ {
+       model = "MPC8560ADS";
+       compatible = "MPC85xxADS";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       linux,phandle = <100>;
+
+       cpus {
+               #cpus = <1>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               linux,phandle = <200>;
+
+               PowerPC,8560@0 {
+                       device_type = "cpu";
+                       reg = <0>;
+                       d-cache-line-size = <20>;       // 32 bytes
+                       i-cache-line-size = <20>;       // 32 bytes
+                       d-cache-size = <8000>;          // L1, 32K
+                       i-cache-size = <8000>;          // L1, 32K
+                       timebase-frequency = <04ead9a0>;
+                       bus-frequency = <13ab6680>;
+                       clock-frequency = <312c8040>;
+                       32-bit;
+                       linux,phandle = <201>;
+                       linux,boot-cpu;
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               linux,phandle = <300>;
+               reg = <00000000 10000000>;
+       };
+
+       soc8560@e0000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               #interrupt-cells = <2>;
+               device_type = "soc";
+               ranges = <0 e0000000 00100000>;
+               reg = <e0000000 00000200>;
+               bus-frequency = <13ab6680>;
+
+               mdio@24520 {
+                       device_type = "mdio";
+                       compatible = "gianfar";
+                       reg = <24520 20>;
+                       linux,phandle = <24520>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ethernet-phy@0 {
+                               linux,phandle = <2452000>;
+                               interrupt-parent = <40000>;
+                               interrupts = <35 1>;
+                               reg = <0>;
+                               device_type = "ethernet-phy";
+                       };
+                       ethernet-phy@1 {
+                               linux,phandle = <2452001>;
+                               interrupt-parent = <40000>;
+                               interrupts = <35 1>;
+                               reg = <1>;
+                               device_type = "ethernet-phy";
+                       };
+                       ethernet-phy@2 {
+                               linux,phandle = <2452002>;
+                               interrupt-parent = <40000>;
+                               interrupts = <37 1>;
+                               reg = <2>;
+                               device_type = "ethernet-phy";
+                       };
+                       ethernet-phy@3 {
+                               linux,phandle = <2452003>;
+                               interrupt-parent = <40000>;
+                               interrupts = <37 1>;
+                               reg = <3>;
+                               device_type = "ethernet-phy";
+                       };
+               };
+
+               ethernet@24000 {
+                       device_type = "network";
+                       model = "TSEC";
+                       compatible = "gianfar";
+                       reg = <24000 1000>;
+                       address = [ 00 00 0C 00 00 FD ];
+                       interrupts = <d 2 e 2 12 2>;
+                       interrupt-parent = <40000>;
+                       phy-handle = <2452000>;
+               };
+
+               ethernet@25000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       device_type = "network";
+                       model = "TSEC";
+                       compatible = "gianfar";
+                       reg = <25000 1000>;
+                       address = [ 00 00 0C 00 01 FD ];
+                       interrupts = <13 2 14 2 18 2>;
+                       interrupt-parent = <40000>;
+                       phy-handle = <2452001>;
+               };
+
+               pci@8000 {
+                       linux,phandle = <8000>;
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       compatible = "85xx";
+                       device_type = "pci";
+                       reg = <8000 400>;
+                       clock-frequency = <3f940aa>;
+                       interrupt-map-mask = <f800 0 0 7>;
+                       interrupt-map = <
+
+                                       /* IDSEL 0x2 */
+                                        1000 0 0 1 40000 31 1
+                                        1000 0 0 2 40000 32 1
+                                        1000 0 0 3 40000 33 1
+                                        1000 0 0 4 40000 34 1
+
+                                       /* IDSEL 0x3 */
+                                        1800 0 0 1 40000 34 1
+                                        1800 0 0 2 40000 31 1
+                                        1800 0 0 3 40000 32 1
+                                        1800 0 0 4 40000 33 1
+
+                                       /* IDSEL 0x4 */
+                                        2000 0 0 1 40000 33 1
+                                        2000 0 0 2 40000 34 1
+                                        2000 0 0 3 40000 31 1
+                                        2000 0 0 4 40000 32 1
+
+                                       /* IDSEL 0x5  */
+                                        2800 0 0 1 40000 32 1
+                                        2800 0 0 2 40000 33 1
+                                        2800 0 0 3 40000 34 1
+                                        2800 0 0 4 40000 31 1
+
+                                       /* IDSEL 12 */
+                                        6000 0 0 1 40000 31 1
+                                        6000 0 0 2 40000 32 1
+                                        6000 0 0 3 40000 33 1
+                                        6000 0 0 4 40000 34 1
+
+                                       /* IDSEL 13 */
+                                        6800 0 0 1 40000 34 1
+                                        6800 0 0 2 40000 31 1
+                                        6800 0 0 3 40000 32 1
+                                        6800 0 0 4 40000 33 1
+
+                                       /* IDSEL 14*/
+                                        7000 0 0 1 40000 33 1
+                                        7000 0 0 2 40000 34 1
+                                        7000 0 0 3 40000 31 1
+                                        7000 0 0 4 40000 32 1
+
+                                       /* IDSEL 15 */
+                                        7800 0 0 1 40000 32 1
+                                        7800 0 0 2 40000 33 1
+                                        7800 0 0 3 40000 34 1
+                                        7800 0 0 4 40000 31 1
+
+                                       /* IDSEL 18 */
+                                        9000 0 0 1 40000 31 1
+                                        9000 0 0 2 40000 32 1
+                                        9000 0 0 3 40000 33 1
+                                        9000 0 0 4 40000 34 1
+
+                                       /* IDSEL 19 */
+                                        9800 0 0 1 40000 34 1
+                                        9800 0 0 2 40000 31 1
+                                        9800 0 0 3 40000 32 1
+                                        9800 0 0 4 40000 33 1
+
+                                       /* IDSEL 20 */
+                                        a000 0 0 1 40000 33 1
+                                        a000 0 0 2 40000 34 1
+                                        a000 0 0 3 40000 31 1
+                                        a000 0 0 4 40000 32 1
+
+                                       /* IDSEL 21 */
+                                        a800 0 0 1 40000 32 1
+                                        a800 0 0 2 40000 33 1
+                                        a800 0 0 3 40000 34 1
+                                        a800 0 0 4 40000 31 1>;
+
+                       interrupt-parent = <40000>;
+                       interrupts = <42 0>;
+                       bus-range = <0 0>;
+                       ranges = <02000000 0 80000000 80000000 0 20000000
+                                 01000000 0 00000000 e2000000 0 01000000>;
+               };
+
+               pic@40000 {
+                       linux,phandle = <40000>;
+                       interrupt-controller;
+                       #address-cells = <0>;
+                       #interrupt-cells = <2>;
+                       reg = <40000 20100>;
+                       built-in;
+                       device_type = "open-pic";
+               };
+
+               cpm@e0000000 {
+                       linux,phandle = <e0000000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       #interrupt-cells = <2>;
+                       device_type = "cpm";
+                       model = "CPM2";
+                       ranges = <0 0 c0000>;
+                       reg = <80000 40000>;
+                       command-proc = <919c0>;
+                       brg-frequency = <9d5b340>;
+
+                       pic@90c00 {
+                               linux,phandle = <90c00>;
+                               interrupt-controller;
+                               #address-cells = <0>;
+                               #interrupt-cells = <2>;
+                               interrupts = <1e 0>;
+                               interrupt-parent = <40000>;
+                               reg = <90c00 80>;
+                               built-in;
+                               device_type = "cpm-pic";
+                       };
+
+                       scc@91a00 {
+                               device_type = "serial";
+                               compatible = "cpm_uart";
+                               model = "SCC";
+                               device-id = <1>;
+                               reg = <91a00 20 88000 100>;
+                               clock-setup = <00ffffff 0>;
+                               rx-clock = <1>;
+                               tx-clock = <1>;
+                               current-speed = <1c200>;
+                               interrupts = <64 1>;
+                               interrupt-parent = <90c00>;
+                       };
+
+                       scc@91a20 {
+                               device_type = "serial";
+                               compatible = "cpm_uart";
+                               model = "SCC";
+                               device-id = <2>;
+                               reg = <91a20 20 88100 100>;
+                               clock-setup = <ff00ffff 90000>;
+                               rx-clock = <2>;
+                               tx-clock = <2>;
+                               current-speed = <1c200>;
+                               interrupts = <65 1>;
+                               interrupt-parent = <90c00>;
+                       };
+
+                       fcc@91320 {
+                               device_type = "network";
+                               compatible = "fs_enet";
+                               model = "FCC";
+                               device-id = <2>;
+                               reg = <91320 20 88500 100 913a0 30>;
+                               mac-address = [ 00 00 0C 00 02 FD ];
+                               clock-setup = <ff00ffff 250000>;
+                               rx-clock = <15>;
+                               tx-clock = <16>;
+                               interrupts = <5d 1>;
+                               interrupt-parent = <90c00>;
+                               phy-handle = <2452002>;
+                       };
+
+                       fcc@91340 {
+                               device_type = "network";
+                               compatible = "fs_enet";
+                               model = "FCC";
+                               device-id = <3>;
+                               reg = <91340 20 88600 100 913d0 30>;
+                               mac-address = [ 00 00 0C 00 03 FD ];
+                               clock-setup = <ffff00ff 3700>;
+                               rx-clock = <17>;
+                               tx-clock = <18>;
+                               interrupts = <5e 1>;
+                               interrupt-parent = <90c00>;
+                               phy-handle = <2452003>;
+                       };
+               };
+       };
+};
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
new file mode 100755 (executable)
index 0000000..eab7318
--- /dev/null
@@ -0,0 +1,204 @@
+#!/bin/sh
+
+# Copyright (C) 2006 Paul Mackerras, IBM Corporation <paulus@samba.org>
+# This program may be used under the terms of version 2 of the GNU
+# General Public License.
+
+# This script takes a kernel binary and optionally an initrd image
+# and/or a device-tree blob, and creates a bootable zImage for a
+# given platform.
+
+# Options:
+# -o zImage    specify output file
+# -p platform  specify platform (links in $platform.o)
+# -i initrd    specify initrd file
+# -d devtree   specify device-tree blob
+# -s tree.dts  specify device-tree source file (needs dtc installed)
+# -c           cache $kernel.strip.gz (use if present & newer, else make)
+# -C prefix    specify command prefix for cross-building tools
+#              (strip, objcopy, ld)
+# -D dir       specify directory containing data files used by script
+#              (default ./arch/powerpc/boot)
+# -W dir       specify working directory for temporary files (default .)
+
+# defaults
+kernel=
+ofile=zImage
+platform=of
+initrd=
+dtb=
+dts=
+cacheit=
+
+# cross-compilation prefix
+CROSS=
+
+# directory for object and other files used by this script
+object=arch/powerpc/boot
+
+# directory for working files
+tmpdir=.
+
+usage() {
+    echo 'Usage: wrapper [-o output] [-p platform] [-i initrd]' >&2
+    echo '       [-d devtree] [-s tree.dts] [-c] [-C cross-prefix]' >&2
+    echo '       [-D datadir] [-W workingdir] [vmlinux]' >&2
+    exit 1
+}
+
+while [ "$#" -gt 0 ]; do
+    case "$1" in
+    -o)
+       shift
+       [ "$#" -gt 0 ] || usage
+       ofile="$1"
+       ;;
+    -p)
+       shift
+       [ "$#" -gt 0 ] || usage
+       platform="$1"
+       ;;
+    -i)
+       shift
+       [ "$#" -gt 0 ] || usage
+       initrd="$1"
+       ;;
+    -d)
+       shift
+       [ "$#" -gt 0 ] || usage
+       dtb="$1"
+       ;;
+    -s)
+       shift
+       [ "$#" -gt 0 ] || usage
+       dts="$1"
+       ;;
+    -c)
+       cacheit=y
+       ;;
+    -C)
+       shift
+       [ "$#" -gt 0 ] || usage
+       CROSS="$1"
+       ;;
+    -D)
+       shift
+       [ "$#" -gt 0 ] || usage
+       object="$1"
+       ;;
+    -W)
+       shift
+       [ "$#" -gt 0 ] || usage
+       tmpdir="$1"
+       ;;
+    -?)
+       usage
+       ;;
+    *)
+       [ -z "$kernel" ] || usage
+       kernel="$1"
+       ;;
+    esac
+    shift
+done
+
+if [ -n "$dts" ]; then
+    if [ -z "$dtb" ]; then
+       dtb="$platform.dtb"
+    fi
+    dtc -O dtb -o "$dtb" -b 0 -V 16 "$dts" || exit 1
+fi
+
+if [ -z "$kernel" ]; then
+    kernel=vmlinux
+fi
+
+platformo=$object/"$platform".o
+lds=$object/zImage.lds
+ext=strip
+objflags=-S
+tmp=$tmpdir/zImage.$$.o
+ksection=.kernel:vmlinux.strip
+isection=.kernel:initrd
+
+case "$platform" in
+pmac|pseries|chrp)
+    platformo=$object/of.o
+    ;;
+pmaccoff)
+    platformo=$object/of.o
+    lds=$object/zImage.coff.lds
+    ;;
+miboot|uboot)
+    # miboot and U-boot want just the bare bits, not an ELF binary
+    ext=bin
+    objflags="-O binary"
+    tmp="$ofile"
+    ksection=image
+    isection=initrd
+    ;;
+esac
+
+vmz="$tmpdir/`basename \"$kernel\"`.$ext"
+if [ -z "$cacheit" -o ! -f "$vmz.gz" -o "$vmz.gz" -ot "$kernel" ]; then
+    ${CROSS}objcopy $objflags "$kernel" "$vmz.$$"
+    gzip -f -9 "$vmz.$$"
+    if [ -n "$cacheit" ]; then
+       mv -f "$vmz.$$.gz" "$vmz.gz"
+    else
+       vmz="$vmz.$$"
+    fi
+fi
+
+case "$platform" in
+uboot)
+    rm -f "$ofile"
+    version=`${CROSS}strings "$kernel" | grep '^Linux version [-0-9.]' | \
+       cut -d' ' -f3`
+    if [ -n "$version" ]; then
+       version="-n Linux-$version"
+    fi
+    mkimage -A ppc -O linux -T kernel -C gzip -a 00000000 -e 00000000 \
+       $version -d "$vmz.gz" "$ofile"
+    if [ -z "$cacheit" ]; then
+       rm -f $vmz.gz
+    fi
+    exit 0
+    ;;
+esac
+
+addsec() {
+    ${CROSS}objcopy $4 $1 \
+       --add-section=$3="$2" \
+       --set-section-flags=$3=contents,alloc,load,readonly,data
+}
+
+addsec $tmp "$vmz.gz" $ksection $object/empty.o
+if [ -z "$cacheit" ]; then
+    rm -f "$vmz.gz"
+fi
+
+if [ -n "$initrd" ]; then
+    addsec $tmp "$initrd" initrd
+fi
+
+if [ -n "$dtb" ]; then
+    addsec $tmp "$dtb" dtb
+fi
+
+if [ "$platform" != "miboot" ]; then
+    ${CROSS}ld -m elf32ppc -T $lds -o "$ofile" \
+       $object/crt0.o $platformo $tmp $object/wrapper.a
+    rm $tmp
+fi
+
+# post-processing needed for some platforms
+case "$platform" in
+pseries|chrp)
+    $object/addnote "$ofile"
+    ;;
+pmaccoff)
+    ${CROSS}objcopy -O aixcoff-rs6000 --set-start 0x500000 "$ofile"
+    $object/hack-coff "$ofile"
+    ;;
+esac
similarity index 96%
rename from arch/powerpc/boot/zImage.coff.lds
rename to arch/powerpc/boot/zImage.coff.lds.S
index 6016251a1a2c73bcc35be2b697c469346683aa15..05f32388b953026924c90834b13a838faabbda35 100644 (file)
@@ -15,6 +15,7 @@ SECTIONS
   {
     *(.rodata*)
     *(.data*)
+    *(__builtin_*)
     *(.sdata*)
     __got2_start = .;
     *(.got2)
index bbf2b5f8a8cbe739a2f465b2c18ea97ecddd7aec..fee72f8a2fb76858fc3323228966bed3fbf94031 100644 (file)
@@ -492,7 +492,7 @@ CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_ATA is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
index 4b9c2ed925f505b5b70ca001ac91547c6fda2703..92d0a9dd0b8f67a4655745b18ef58097f83b5556 100644 (file)
@@ -490,23 +490,23 @@ CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-CONFIG_SCSI_SATA=y
-# CONFIG_SCSI_SATA_AHCI is not set
-CONFIG_SCSI_SATA_SVW=y
+CONFIG_ATA=y
+# CONFIG_SATA_AHCI is not set
+CONFIG_SATA_SVW=y
 # CONFIG_SCSI_ATA_PIIX is not set
-# CONFIG_SCSI_SATA_MV is not set
-# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
 # CONFIG_SCSI_PDC_ADMA is not set
 # CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_SATA_QSTOR is not set
-# CONFIG_SCSI_SATA_PROMISE is not set
-# CONFIG_SCSI_SATA_SX4 is not set
-# CONFIG_SCSI_SATA_SIL is not set
-# CONFIG_SCSI_SATA_SIL24 is not set
-# CONFIG_SCSI_SATA_SIS is not set
-# CONFIG_SCSI_SATA_ULI is not set
-# CONFIG_SCSI_SATA_VIA is not set
-# CONFIG_SCSI_SATA_VITESSE is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
index eb0885ea073178ac09b9cea142803099ce471865..d58f82f836f82553e9c5b98bd0dce39f55afda38 100644 (file)
@@ -475,7 +475,7 @@ CONFIG_SCSI_FC_ATTRS=y
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_ATA is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
index 719fba4eb42100833c2103f4a0dbc8e0ed084c66..d1811e754518d01930eafd188391d502e4c5bd8c 100644 (file)
@@ -413,23 +413,23 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-CONFIG_SCSI_SATA=y
-# CONFIG_SCSI_SATA_AHCI is not set
-# CONFIG_SCSI_SATA_SVW is not set
+CONFIG_ATA=y
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
 # CONFIG_SCSI_ATA_PIIX is not set
-CONFIG_SCSI_SATA_MV=y
-# CONFIG_SCSI_SATA_NV is not set
+CONFIG_SATA_MV=y
+# CONFIG_SATA_NV is not set
 # CONFIG_SCSI_PDC_ADMA is not set
 # CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_SATA_QSTOR is not set
-# CONFIG_SCSI_SATA_PROMISE is not set
-# CONFIG_SCSI_SATA_SX4 is not set
-# CONFIG_SCSI_SATA_SIL is not set
-# CONFIG_SCSI_SATA_SIL24 is not set
-# CONFIG_SCSI_SATA_SIS is not set
-# CONFIG_SCSI_SATA_ULI is not set
-# CONFIG_SCSI_SATA_VIA is not set
-# CONFIG_SCSI_SATA_VITESSE is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
index 8da6a47f03390b2765c17ca020244a37972379b8..cd3535e1a09558d323b351fd52b87c7c2831c692 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc6
-# Sun Sep 10 10:28:05 2006
+# Linux kernel version: 2.6.18
+# Mon Sep 25 19:41:14 2006
 #
 # CONFIG_PPC64 is not set
 CONFIG_PPC32=y
@@ -21,6 +21,7 @@ CONFIG_ARCH_MAY_HAVE_PC_FDC=y
 CONFIG_PPC_OF=y
 CONFIG_PPC_UDBG_16550=y
 # CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
 CONFIG_DEFAULT_UIMAGE=y
 
 #
@@ -61,25 +62,25 @@ CONFIG_SYSVIPC=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL=y
 # CONFIG_KALLSYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 # CONFIG_EPOLL is not set
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -259,7 +260,6 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -313,6 +313,7 @@ CONFIG_MTD_CHAR=y
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -464,23 +465,23 @@ CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-CONFIG_SCSI_SATA=y
-# CONFIG_SCSI_SATA_AHCI is not set
-# CONFIG_SCSI_SATA_SVW is not set
+CONFIG_ATA=y
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
 # CONFIG_SCSI_ATA_PIIX is not set
-# CONFIG_SCSI_SATA_MV is not set
-# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
 # CONFIG_SCSI_PDC_ADMA is not set
 # CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_SATA_QSTOR is not set
-# CONFIG_SCSI_SATA_PROMISE is not set
-# CONFIG_SCSI_SATA_SX4 is not set
-CONFIG_SCSI_SATA_SIL=y
-# CONFIG_SCSI_SATA_SIL24 is not set
-# CONFIG_SCSI_SATA_SIS is not set
-# CONFIG_SCSI_SATA_ULI is not set
-# CONFIG_SCSI_SATA_VIA is not set
-# CONFIG_SCSI_SATA_VITESSE is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+CONFIG_SATA_SIL=y
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
@@ -1277,11 +1278,11 @@ CONFIG_PLIST=y
 #
 # Kernel hacking
 #
-CONFIG_PRINTK_TIME=y
+# CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_KERNEL=y
-CONFIG_LOG_BUF_SHIFT=17
+CONFIG_LOG_BUF_SHIFT=14
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
@@ -1293,15 +1294,15 @@ CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
-CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_DEBUGGER is not set
 # CONFIG_BDI_SWITCH is not set
-CONFIG_BOOTX_TEXT=y
-CONFIG_SERIAL_TEXT_DEBUG=y
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_SERIAL_TEXT_DEBUG is not set
 # CONFIG_PPC_EARLY_DEBUG is not set
 
 #
@@ -1314,6 +1315,8 @@ CONFIG_SERIAL_TEXT_DEBUG=y
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+# CONFIG_CRYPTO_MANAGER is not set
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
@@ -1323,6 +1326,8 @@ CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_CBC is not set
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
diff --git a/arch/powerpc/configs/mpc8360emds_defconfig b/arch/powerpc/configs/mpc8360emds_defconfig
new file mode 100644 (file)
index 0000000..c070341
--- /dev/null
@@ -0,0 +1,1018 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18
+# Thu Sep 21 18:14:27 2006
+#
+# CONFIG_PPC64 is not set
+CONFIG_PPC32=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_DEFAULT_UIMAGE=y
+
+#
+# Processor support
+#
+# CONFIG_CLASSIC32 is not set
+# CONFIG_PPC_52xx is not set
+# CONFIG_PPC_82xx is not set
+CONFIG_PPC_83xx=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_86xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_8xx is not set
+# CONFIG_E200 is not set
+CONFIG_6xx=y
+CONFIG_83xx=y
+CONFIG_PPC_FPU=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_SMP is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL=y
+# CONFIG_KALLSYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+# CONFIG_EPOLL is not set
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_QUICC_ENGINE=y
+CONFIG_PPC_GEN550=y
+# CONFIG_WANT_EARLY_SERIAL is not set
+
+#
+# Platform support
+#
+# CONFIG_MPC834x_SYS is not set
+# CONFIG_MPC834x_ITX is not set
+CONFIG_MPC8360E_PB=y
+CONFIG_PPC_MPC836x=y
+# CONFIG_MPIC is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_GENERIC_ISA_DMA=y
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_FSL_SOC=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCIEPORTBUS is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_BOOT_LOAD=0x00800000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=32768
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+# CONFIG_BLK_DEV_SD is not set
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+# CONFIG_WINDFARM is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_GIANFAR is not set
+CONFIG_UCC_GETH=y
+# CONFIG_UGETH_NAPI is not set
+# CONFIG_UGETH_MAGIC_PACKET is not set
+# CONFIG_UGETH_FILTERING is not set
+# CONFIG_UGETH_TX_ON_DEMOND is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_83xx_WDT=y
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+CONFIG_I2C_MPC=y
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_M41T00 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# QE Options
+#
+# CONFIG_UCC_SLOW is not set
+CONFIG_UCC_FAST=y
+CONFIG_UCC=y
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_FS is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_SERIAL_TEXT_DEBUG is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
similarity index 58%
rename from arch/mips/configs/ivr_defconfig
rename to arch/powerpc/configs/mpc8560_ads_defconfig
index 18874a4c24fec8978ea5539c29e36d81265026f6..ddc2a7b07ba0e4d1ce81a5352e808a03fd8b678b 100644 (file)
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:12 2006
-#
-CONFIG_MIPS=y
-
-#
-# Machine selection
-#
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_PB1200 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_DB1200 is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
-# CONFIG_MIPS_COBALT is not set
-# CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
-CONFIG_MIPS_IVR=y
-# CONFIG_MIPS_ITE8172 is not set
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
-# CONFIG_MIPS_ATLAS is not set
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_MIPS_SEAD is not set
-# CONFIG_WR_PPMC is not set
-# CONFIG_MIPS_SIM is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
-# CONFIG_PNX8550_JBS is not set
-# CONFIG_DDB5477 is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_PMC_YOSEMITE is not set
-# CONFIG_QEMU is not set
-# CONFIG_MARKEINS is not set
-# CONFIG_SGI_IP22 is not set
-# CONFIG_SGI_IP27 is not set
-# CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_BIGSUR is not set
-# CONFIG_SIBYTE_SWARM is not set
-# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_PTSWARM is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
-# CONFIG_SIBYTE_CRHINE is not set
-# CONFIG_SIBYTE_CRHONE is not set
-# CONFIG_SNI_RM200_PCI is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_TOSHIBA_RBTX4938 is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_FIND_NEXT_BIT=y
+# Linux kernel version: 2.6.18-rc4
+# Fri Aug 11 16:45:05 2006
+#
+# CONFIG_PPC64 is not set
+CONFIG_PPC32=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_NEED_PCI_MAP_STATE=y
-# CONFIG_CPU_BIG_ENDIAN is not set
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_ITE_BOARD_GEN=y
-CONFIG_IT8172_CIR=y
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-
-#
-# CPU selection
-#
-# CONFIG_CPU_MIPS32_R1 is not set
-# CONFIG_CPU_MIPS32_R2 is not set
-# CONFIG_CPU_MIPS64_R1 is not set
-# CONFIG_CPU_MIPS64_R2 is not set
-# CONFIG_CPU_R3000 is not set
-# CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_VR41XX is not set
-# CONFIG_CPU_R4300 is not set
-# CONFIG_CPU_R4X00 is not set
-# CONFIG_CPU_TX49XX is not set
-# CONFIG_CPU_R5000 is not set
-# CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_R6000 is not set
-CONFIG_CPU_NEVADA=y
-# CONFIG_CPU_R8000 is not set
-# CONFIG_CPU_R10000 is not set
-# CONFIG_CPU_RM7000 is not set
-# CONFIG_CPU_RM9000 is not set
-# CONFIG_CPU_SB1 is not set
-CONFIG_SYS_HAS_CPU_NEVADA=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
-
-#
-# Kernel type
-#
-CONFIG_32BIT=y
-# CONFIG_64BIT is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_8KB is not set
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
-CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
-# CONFIG_MIPS_MT_SMP is not set
-# CONFIG_MIPS_VPE_LOADER is not set
-CONFIG_CPU_HAS_LLSC=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_ARCH_FLATMEM_ENABLE=y
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
-# CONFIG_HZ_48 is not set
-# CONFIG_HZ_100 is not set
-# CONFIG_HZ_128 is not set
-# CONFIG_HZ_250 is not set
-# CONFIG_HZ_256 is not set
-CONFIG_HZ_1000=y
-# CONFIG_HZ_1024 is not set
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=1000
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+# CONFIG_PPC_UDBG_16550 is not set
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_DEFAULT_UIMAGE=y
+
+#
+# Processor support
+#
+# CONFIG_CLASSIC32 is not set
+# CONFIG_PPC_52xx is not set
+# CONFIG_PPC_82xx is not set
+# CONFIG_PPC_83xx is not set
+CONFIG_PPC_85xx=y
+# CONFIG_PPC_86xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_8xx is not set
+# CONFIG_E200 is not set
+CONFIG_85xx=y
+CONFIG_E500=y
+CONFIG_BOOKE=y
+CONFIG_FSL_BOOKE=y
+# CONFIG_PHYS_64BIT is not set
+CONFIG_SPE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -161,16 +59,17 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_POSIX_MQUEUE is not set
-CONFIG_BSD_PROCESS_ACCT=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
-CONFIG_RELAY=y
+# CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
@@ -190,12 +89,7 @@ CONFIG_BASE_SMALL=0
 #
 # Loadable module support
 #
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
+# CONFIG_MODULES is not set
 
 #
 # Block layer
@@ -216,13 +110,62 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_MPIC=y
+CONFIG_CPM2=y
+# CONFIG_WANT_EARLY_SERIAL is not set
+
+#
+# Platform support
+#
+# CONFIG_MPC8540_ADS is not set
+CONFIG_MPC8560_ADS=y
+# CONFIG_MPC85xx_CDS is not set
+CONFIG_MPC8560=y
+CONFIG_PPC_INDIRECT_PCI_BE=y
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+# CONFIG_MATH_EMULATION is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+# CONFIG_PC_KEYBOARD is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PROC_DEVICETREE is not set
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+# CONFIG_SOFTWARE_SUSPEND is not set
+# CONFIG_SECCOMP is not set
+CONFIG_ISA_DMA_API=y
 
 #
-# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+# Bus options
 #
-CONFIG_HW_HAS_PCI=y
+# CONFIG_PPC_I8259 is not set
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_FSL_SOC=y
 CONFIG_PCI=y
-CONFIG_MMU=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCIEPORTBUS is not set
+CONFIG_PCI_DEBUG=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -235,11 +178,18 @@ CONFIG_MMU=y
 # CONFIG_HOTPLUG_PCI is not set
 
 #
-# Executable file formats
+# Advanced setup
 #
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_TRAD_SIGNALS=y
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_BOOT_LOAD=0x00800000
 
 #
 # Networking
@@ -251,30 +201,31 @@ CONFIG_NET=y
 #
 # CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
+# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-CONFIG_NET_KEY=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_NET_KEY is not set
 CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_FIB_HASH=y
 CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
 # CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
+CONFIG_SYN_COOKIES=y
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -282,7 +233,7 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
-CONFIG_NETWORK_SECMARK=y
+# CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 
 #
@@ -324,13 +275,7 @@ CONFIG_NETWORK_SECMARK=y
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-CONFIG_IEEE80211=m
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=m
-CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_SOFTMAC=m
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
-CONFIG_WIRELESS_EXT=y
+# CONFIG_IEEE80211 is not set
 
 #
 # Device Drivers
@@ -341,13 +286,14 @@ CONFIG_WIRELESS_EXT=y
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
 # CONFIG_SYS_HYPERVISOR is not set
 
 #
 # Connector - unified userspace <-> kernelspace linker
 #
-CONFIG_CONNECTOR=m
+# CONFIG_CONNECTOR is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -366,52 +312,33 @@ CONFIG_CONNECTOR=m
 #
 # Block devices
 #
+# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-CONFIG_ATA_OVER_ETH=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=32768
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
 
 #
 # ATA/ATAPI/MFM/RLL support
 #
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-# CONFIG_BLK_DEV_IDEPCI is not set
-# CONFIG_IDE_ARM is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
+# CONFIG_IDE is not set
 
 #
 # SCSI device support
 #
-CONFIG_RAID_ATTRS=m
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 
 #
@@ -434,6 +361,11 @@ CONFIG_RAID_ATTRS=m
 #
 # CONFIG_I2O is not set
 
+#
+# Macintosh device drivers
+#
+# CONFIG_WINDFARM is not set
+
 #
 # Network device support
 #
@@ -451,29 +383,29 @@ CONFIG_NETDEVICES=y
 #
 # PHY device support
 #
-CONFIG_PHYLIB=m
+CONFIG_PHYLIB=y
 
 #
 # MII PHY device drivers
 #
-CONFIG_MARVELL_PHY=m
-CONFIG_DAVICOM_PHY=m
-CONFIG_QSEMI_PHY=m
-CONFIG_LXT_PHY=m
-CONFIG_CICADA_PHY=m
-CONFIG_VITESSE_PHY=m
-CONFIG_SMSC_PHY=m
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
+CONFIG_MII=y
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -481,13 +413,18 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 # CONFIG_NET_PCI is not set
+CONFIG_FS_ENET=y
+# CONFIG_FS_ENET_HAS_SCC is not set
+CONFIG_FS_ENET_HAS_FCC=y
 
 #
 # Ethernet (1000 Mbit)
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
+CONFIG_E1000=y
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -498,6 +435,8 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_GIANFAR=y
+CONFIG_GFAR_NAPI=y
 
 #
 # Ethernet (10000 Mbit)
@@ -548,10 +487,7 @@ CONFIG_INPUT=y
 #
 # Userland interfaces
 #
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_JOYDEV is not set
 # CONFIG_INPUT_TSDEV is not set
 # CONFIG_INPUT_EVDEV is not set
@@ -569,45 +505,38 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 #
 # Hardware I/O ports
 #
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
+# CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
 
 #
 # Character devices
 #
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_VT is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
-CONFIG_QTRONIX_KEYBOARD=y
-CONFIG_IT8172_SCR0=y
-CONFIG_IT8172_SCR1=y
 
 #
 # Serial drivers
 #
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_PCI=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250 is not set
 
 #
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_CPM=y
+CONFIG_SERIAL_CPM_CONSOLE=y
+CONFIG_SERIAL_CPM_SCC1=y
+CONFIG_SERIAL_CPM_SCC2=y
+# CONFIG_SERIAL_CPM_SCC3 is not set
+# CONFIG_SERIAL_CPM_SCC4 is not set
+# CONFIG_SERIAL_CPM_SMC1 is not set
+# CONFIG_SERIAL_CPM_SMC2 is not set
 # CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_BRIQ_PANEL is not set
 
 #
 # IPMI
@@ -618,8 +547,10 @@ CONFIG_LEGACY_PTY_COUNT=256
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_HW_RANDOM is not set
-CONFIG_RTC=y
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -627,6 +558,7 @@ CONFIG_RTC=y
 #
 # Ftape, the floppy tape device driver
 #
+# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -650,13 +582,15 @@ CONFIG_RTC=y
 #
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
 #
-# CONFIG_HWMON is not set
+CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -676,14 +610,9 @@ CONFIG_VIDEO_V4L2=y
 #
 # Graphics support
 #
-# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -758,7 +687,13 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
-# CONFIG_EXT3_FS is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -772,7 +707,7 @@ CONFIG_INOTIFY_USER=y
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
-CONFIG_FUSE_FS=m
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -793,7 +728,7 @@ CONFIG_FUSE_FS=m
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
+CONFIG_TMPFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
@@ -831,7 +766,6 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -840,8 +774,19 @@ CONFIG_SUNRPC=y
 #
 # Partition Types
 #
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
 
 #
 # Native Language Support
@@ -849,7 +794,16 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_NLS is not set
 
 #
-# Profiling support
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+
+#
+# Instrumentation Support
 #
 # CONFIG_PROFILING is not set
 
@@ -859,59 +813,42 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_RWSEMS is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_FS is not set
-CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+# CONFIG_DEBUG_VM is not set
+# CONFIG_UNWIND_INFO is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_DEBUGGER is not set
+# CONFIG_KGDB_CONSOLE is not set
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
 
 #
 # Security options
 #
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 
 #
 # Cryptographic options
 #
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO is not set
 
 #
 # Hardware crypto devices
 #
-
-#
-# Library routines
-#
-# CONFIG_CRC_CCITT is not set
-CONFIG_CRC16=m
-CONFIG_CRC32=m
-CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=m
-CONFIG_ZLIB_DEFLATE=m
-CONFIG_PLIST=y
index 6861dde7d77bc54a3951defd0de5cb28c63a85ea..765c8bb90ddd12078bd92b725c7d3d4081a71e2b 100644 (file)
@@ -682,7 +682,7 @@ CONFIG_SCSI_AIC7XXX_OLD=m
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_ATA is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
@@ -1826,7 +1826,7 @@ CONFIG_OPROFILE=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=14
index 7517d0c5303fc1803a73dee77157628e61abdc29..be11df7c11aa4ea455022791b7e8847449f371ee 100644 (file)
@@ -520,23 +520,23 @@ CONFIG_SCSI_ISCSI_ATTRS=m
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-CONFIG_SCSI_SATA=y
-# CONFIG_SCSI_SATA_AHCI is not set
-CONFIG_SCSI_SATA_SVW=y
+CONFIG_ATA=y
+# CONFIG_SATA_AHCI is not set
+CONFIG_SATA_SVW=y
 # CONFIG_SCSI_ATA_PIIX is not set
-# CONFIG_SCSI_SATA_MV is not set
-# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
 # CONFIG_SCSI_PDC_ADMA is not set
 # CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_SATA_QSTOR is not set
-# CONFIG_SCSI_SATA_PROMISE is not set
-# CONFIG_SCSI_SATA_SX4 is not set
-# CONFIG_SCSI_SATA_SIL is not set
-# CONFIG_SCSI_SATA_SIL24 is not set
-# CONFIG_SCSI_SATA_SIS is not set
-# CONFIG_SCSI_SATA_ULI is not set
-# CONFIG_SCSI_SATA_VIA is not set
-# CONFIG_SCSI_SATA_VITESSE is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
index a8cdf312e1b0fbc4a8d79101913fc1f31f27b2f7..44175fb7adecc7822dab452201833373eaffddcf 100644 (file)
@@ -506,7 +506,7 @@ CONFIG_SCSI_SAS_ATTRS=m
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_ATA is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
index 190a57e2076545a871a5a297366c50b0f899d1a5..47a613cdd775ce11535dbc214886bb446f9437f3 100644 (file)
@@ -763,10 +763,10 @@ struct cpu_spec   cpu_specs[] = {
                .cpu_setup              = __setup_cpu_603,
                .platform               = "ppc603",
        },
-       {       /* e300 (a 603e core, plus some) on 83xx */
+       {       /* e300c1 (a 603e core, plus some) on 83xx */
                .pvr_mask               = 0x7fff0000,
                .pvr_value              = 0x00830000,
-               .cpu_name               = "e300",
+               .cpu_name               = "e300c1",
                .cpu_features           = CPU_FTRS_E300,
                .cpu_user_features      = COMMON_USER,
                .icache_bsize           = 32,
@@ -774,6 +774,17 @@ struct cpu_spec    cpu_specs[] = {
                .cpu_setup              = __setup_cpu_603,
                .platform               = "ppc603",
        },
+       {       /* e300c2 (an e300c1 core, plus some, minus FPU) on 83xx */
+               .pvr_mask               = 0x7fff0000,
+               .pvr_value              = 0x00840000,
+               .cpu_name               = "e300c2",
+               .cpu_features           = CPU_FTRS_E300,
+               .cpu_user_features      = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+               .icache_bsize           = 32,
+               .dcache_bsize           = 32,
+               .cpu_setup              = __setup_cpu_603,
+               .platform               = "ppc603",
+       },
        {       /* default match, we assume split I/D cache & TB (non-601)... */
                .pvr_mask               = 0x00000000,
                .pvr_value              = 0x00000000,
index 2cd872b5283b7e1c4418f569859ee12f6d18c97b..748e74fcf541f4f1cb4eb6dcdb4694db218f4ec0 100644 (file)
 #include <asm/ppc_asm.h>
 #include <asm/asm-offsets.h>
 #include <asm/cputable.h>
-
-#ifdef CONFIG_PPC_ISERIES
-#define DO_SOFT_DISABLE
-#endif
+#include <asm/firmware.h>
 
 /*
  * System calls.
@@ -91,6 +88,7 @@ system_call_common:
        ld      r11,exception_marker@toc(r2)
        std     r11,-16(r9)             /* "regshere" marker */
 #ifdef CONFIG_PPC_ISERIES
+BEGIN_FW_FTR_SECTION
        /* Hack for handling interrupts when soft-enabling on iSeries */
        cmpdi   cr1,r0,0x5555           /* syscall 0x5555 */
        andi.   r10,r12,MSR_PR          /* from kernel */
@@ -98,6 +96,7 @@ system_call_common:
        beq     hardware_interrupt_entry
        lbz     r10,PACAPROCENABLED(r13)
        std     r10,SOFTE(r1)
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif
        mfmsr   r11
        ori     r11,r11,MSR_EE
@@ -462,6 +461,7 @@ _GLOBAL(ret_from_except_lite)
 
 restore:
 #ifdef CONFIG_PPC_ISERIES
+BEGIN_FW_FTR_SECTION
        ld      r5,SOFTE(r1)
        cmpdi   0,r5,0
        beq     4f
@@ -480,6 +480,7 @@ restore:
        b       .ret_from_except_lite           /* loop back and handle more */
 
 4:     stb     r5,PACAPROCENABLED(r13)
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif
 
        ld      r3,_MSR(r1)
@@ -538,18 +539,23 @@ do_work:
        lwz     r8,TI_PREEMPT(r9)
        cmpwi   cr1,r8,0
 #ifdef CONFIG_PPC_ISERIES
+BEGIN_FW_FTR_SECTION
        ld      r0,SOFTE(r1)
        cmpdi   r0,0
-#else
-       andi.   r0,r3,MSR_EE
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif
+BEGIN_FW_FTR_SECTION
+       andi.   r0,r3,MSR_EE
+END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
        crandc  eq,cr1*4+eq,eq
        bne     restore
        /* here we are preempting the current task */
 1:
 #ifdef CONFIG_PPC_ISERIES
+BEGIN_FW_FTR_SECTION
        li      r0,1
        stb     r0,PACAPROCENABLED(r13)
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif
        ori     r10,r10,MSR_EE
        mtmsrd  r10,1           /* reenable interrupts */
index 3065b472b95db7151912d8956933589fce4b736c..645c7f10fb28300b782334e4c264602d80718877 100644 (file)
@@ -33,6 +33,7 @@
 #include <asm/hvcall.h>
 #include <asm/iseries/lpar_map.h>
 #include <asm/thread_info.h>
+#include <asm/firmware.h>
 
 #ifdef CONFIG_PPC_ISERIES
 #define DO_SOFT_DISABLE
@@ -365,19 +366,28 @@ label##_iSeries:                                                  \
 
 #ifdef DO_SOFT_DISABLE
 #define DISABLE_INTS                           \
+BEGIN_FW_FTR_SECTION;                          \
        lbz     r10,PACAPROCENABLED(r13);       \
        li      r11,0;                          \
        std     r10,SOFTE(r1);                  \
        mfmsr   r10;                            \
        stb     r11,PACAPROCENABLED(r13);       \
        ori     r10,r10,MSR_EE;                 \
-       mtmsrd  r10,1
+       mtmsrd  r10,1;                          \
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 
 #define ENABLE_INTS                            \
+BEGIN_FW_FTR_SECTION;                          \
        lbz     r10,PACAPROCENABLED(r13);       \
        mfmsr   r11;                            \
        std     r10,SOFTE(r1);                  \
        ori     r11,r11,MSR_EE;                 \
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES);  \
+BEGIN_FW_FTR_SECTION;                          \
+       ld      r12,_MSR(r1);                   \
+       mfmsr   r11;                            \
+       rlwimi  r11,r12,0,MSR_EE;               \
+END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES);  \
        mtmsrd  r11,1
 
 #else  /* hard enable/disable interrupts */
@@ -1071,8 +1081,10 @@ _GLOBAL(slb_miss_realmode)
        ld      r3,PACA_EXSLB+EX_R3(r13)
        lwz     r9,PACA_EXSLB+EX_CCR(r13)       /* get saved CR */
 #ifdef CONFIG_PPC_ISERIES
+BEGIN_FW_FTR_SECTION
        ld      r11,PACALPPACAPTR(r13)
        ld      r11,LPPACASRR0(r11)             /* get SRR0 value */
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif /* CONFIG_PPC_ISERIES */
 
        mtlr    r10
@@ -1087,8 +1099,10 @@ _GLOBAL(slb_miss_realmode)
 .machine       pop
 
 #ifdef CONFIG_PPC_ISERIES
+BEGIN_FW_FTR_SECTION
        mtspr   SPRN_SRR0,r11
        mtspr   SPRN_SRR1,r12
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif /* CONFIG_PPC_ISERIES */
        ld      r9,PACA_EXSLB+EX_R9(r13)
        ld      r10,PACA_EXSLB+EX_R10(r13)
@@ -1301,6 +1315,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
        cmpdi   r3,0                    /* see if hash_page succeeded */
 
 #ifdef DO_SOFT_DISABLE
+BEGIN_FW_FTR_SECTION
        /*
         * If we had interrupts soft-enabled at the point where the
         * DSI/ISI occurred, and an interrupt came in during hash_page,
@@ -1321,12 +1336,14 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
        ld      r3,SOFTE(r1)
        bl      .local_irq_restore
        b       11f
-#else
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
+#endif
+BEGIN_FW_FTR_SECTION
        beq     fast_exception_return   /* Return from exception on success */
        ble-    12f                     /* Failure return from hash_page */
 
        /* fall through */
-#endif
+END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
 
 /* Here we have a page fault that hash_page can't handle. */
 _GLOBAL(handle_page_fault)
@@ -1861,7 +1878,9 @@ _GLOBAL(__secondary_start)
        LOAD_REG_ADDR(r3, .start_secondary_prolog)
        LOAD_REG_IMMEDIATE(r4, MSR_KERNEL)
 #ifdef DO_SOFT_DISABLE
+BEGIN_FW_FTR_SECTION
        ori     r4,r4,MSR_EE
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif
        mtspr   SPRN_SRR0,r3
        mtspr   SPRN_SRR1,r4
@@ -1986,6 +2005,7 @@ _STATIC(start_here_common)
         */
        li      r3,0
        bl      .do_cpu_ftr_fixups
+       bl      .do_fw_ftr_fixups
 
        /* ptr to current */
        LOAD_REG_IMMEDIATE(r4, init_task)
@@ -2000,11 +2020,13 @@ _STATIC(start_here_common)
        /* Load up the kernel context */
 5:
 #ifdef DO_SOFT_DISABLE
+BEGIN_FW_FTR_SECTION
        li      r5,0
        stb     r5,PACAPROCENABLED(r13) /* Soft Disabled */
        mfmsr   r5
        ori     r5,r5,MSR_EE            /* Hard Enabled */
        mtmsrd  r5
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif
 
        bl .start_kernel
index b4432332341fc6a695b87e0cf4f6b3de1ac520ba..c3f58f2f9f525d15fcb12466c6d7321218b2fc80 100644 (file)
@@ -777,7 +777,6 @@ unsigned int irq_alloc_virt(struct irq_host *host,
 {
        unsigned long flags;
        unsigned int i, j, found = NO_IRQ;
-       unsigned int limit = irq_virq_count - count;
 
        if (count == 0 || count > (irq_virq_count - NUM_ISA_INTERRUPTS))
                return NO_IRQ;
@@ -794,14 +793,16 @@ unsigned int irq_alloc_virt(struct irq_host *host,
        /* Look for count consecutive numbers in the allocatable
         * (non-legacy) space
         */
-       for (i = NUM_ISA_INTERRUPTS; i <= limit; ) {
-               for (j = i; j < (i + count); j++)
-                       if (irq_map[j].host != NULL) {
-                               i = j + 1;
-                               continue;
-                       }
-               found = i;
-               break;
+       for (i = NUM_ISA_INTERRUPTS, j = 0; i < irq_virq_count; i++) {
+               if (irq_map[i].host != NULL)
+                       j = 0;
+               else
+                       j++;
+
+               if (j == count) {
+                       found = i - count + 1;
+                       break;
+               }
        }
        if (found == NO_IRQ) {
                spin_unlock_irqrestore(&irq_big_lock, flags);
index cd65c367b8b6d5c9abcc23fe7cbf595931814a5d..7b8d12b9026c48487fbad3a4b83ca682108db260 100644 (file)
@@ -259,14 +259,15 @@ void kretprobe_trampoline_holder(void)
  */
 int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
 {
-        struct kretprobe_instance *ri = NULL;
-        struct hlist_head *head;
-        struct hlist_node *node, *tmp;
+       struct kretprobe_instance *ri = NULL;
+       struct hlist_head *head, empty_rp;
+       struct hlist_node *node, *tmp;
        unsigned long flags, orig_ret_address = 0;
        unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
 
+       INIT_HLIST_HEAD(&empty_rp);
        spin_lock_irqsave(&kretprobe_lock, flags);
-        head = kretprobe_inst_table_head(current);
+       head = kretprobe_inst_table_head(current);
 
        /*
         * It is possible to have multiple instances associated with a given
@@ -277,20 +278,20 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
         * We can handle this because:
         *     - instances are always inserted at the head of the list
         *     - when multiple return probes are registered for the same
-         *       function, the first instance's ret_addr will point to the
+        *       function, the first instance's ret_addr will point to the
         *       real return address, and all the rest will point to
         *       kretprobe_trampoline
         */
        hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
-                if (ri->task != current)
+               if (ri->task != current)
                        /* another task is sharing our hash bucket */
-                        continue;
+                       continue;
 
                if (ri->rp && ri->rp->handler)
                        ri->rp->handler(ri, regs);
 
                orig_ret_address = (unsigned long)ri->ret_addr;
-               recycle_rp_inst(ri);
+               recycle_rp_inst(ri, &empty_rp);
 
                if (orig_ret_address != trampoline_address)
                        /*
@@ -308,12 +309,16 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
        spin_unlock_irqrestore(&kretprobe_lock, flags);
        preempt_enable_no_resched();
 
-        /*
-         * By returning a non-zero value, we are telling
-         * kprobe_handler() that we don't want the post_handler
-         * to run (and have re-enabled preemption)
-         */
-        return 1;
+       hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
+               hlist_del(&ri->hlist);
+               kfree(ri);
+       }
+       /*
+        * By returning a non-zero value, we are telling
+        * kprobe_handler() that we don't want the post_handler
+        * to run (and have re-enabled preemption)
+        */
+       return 1;
 }
 
 /*
index 58758d8833619f011e10801e0647a2c08b1e8ff1..88fd73fdf048aea647974a694f033653e93cd4f8 100644 (file)
@@ -843,7 +843,7 @@ _GLOBAL(kernel_thread)
        addi    r1,r1,16
        blr
 
-_GLOBAL(execve)
+_GLOBAL(kernel_execve)
        li      r0,__NR_execve
        sc
        bnslr
index e3ed21cd3d945e6d3e5afbfb64108dc5602517f6..41521b30c3cdd36f3a369bf9c8b902b4cb6b22b3 100644 (file)
@@ -325,6 +325,52 @@ _GLOBAL(do_cpu_ftr_fixups)
        isync
        b       1b
 
+/*
+ * do_fw_ftr_fixups - goes through the list of firmware feature fixups
+ * and writes nop's over sections of code that don't apply for this firmware.
+ * r3 = data offset (not changed)
+ */
+_GLOBAL(do_fw_ftr_fixups)
+       /* Get firmware features */
+       LOAD_REG_IMMEDIATE(r6,powerpc_firmware_features)
+       sub     r6,r6,r3
+       ld      r4,0(r6)
+       /* Get the fixup table */
+       LOAD_REG_IMMEDIATE(r6,__start___fw_ftr_fixup)
+       sub     r6,r6,r3
+       LOAD_REG_IMMEDIATE(r7,__stop___fw_ftr_fixup)
+       sub     r7,r7,r3
+       /* Do the fixup */
+1:     cmpld   r6,r7
+       bgelr
+       addi    r6,r6,32
+       ld      r8,-32(r6)      /* mask */
+       and     r8,r8,r4
+       ld      r9,-24(r6)      /* value */
+       cmpld   r8,r9
+       beq     1b
+       ld      r8,-16(r6)      /* section begin */
+       ld      r9,-8(r6)       /* section end */
+       subf.   r9,r8,r9
+       beq     1b
+       /* write nops over the section of code */
+       /* todo: if large section, add a branch at the start of it */
+       srwi    r9,r9,2
+       mtctr   r9
+       sub     r8,r8,r3
+       lis     r0,0x60000000@h /* nop */
+3:     stw     r0,0(r8)
+BEGIN_FTR_SECTION
+       dcbst   0,r8            /* suboptimal, but simpler */
+       sync
+       icbi    0,r8
+END_FTR_SECTION_IFSET(CPU_FTR_SPLIT_ID_CACHE)
+       addi    r8,r8,4
+       bdnz    3b
+       sync                    /* additional sync needed on g4 */
+       isync
+       b       1b
+
 #if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE)
 /*
  * Do an IO access in real mode
@@ -556,7 +602,7 @@ _GLOBAL(giveup_altivec)
 
 #endif /* CONFIG_ALTIVEC */
 
-_GLOBAL(execve)
+_GLOBAL(kernel_execve)
        li      r0,__NR_execve
        sc
        bnslr
index c1b1e14775e41c53a2b0614db015aad71b1b9be3..78d3c0fc8dfbfd1254f77fa44d680c4cdcc27b56 100644 (file)
@@ -30,6 +30,7 @@
 #include <asm/byteorder.h>
 #include <asm/machdep.h>
 #include <asm/ppc-pci.h>
+#include <asm/firmware.h>
 
 #ifdef DEBUG
 #include <asm/udbg.h>
@@ -209,7 +210,6 @@ void pcibios_free_controller(struct pci_controller *phb)
                kfree(phb);
 }
 
-#ifndef CONFIG_PPC_ISERIES
 void __devinit pcibios_claim_one_bus(struct pci_bus *b)
 {
        struct pci_dev *dev;
@@ -238,10 +238,12 @@ static void __init pcibios_claim_of_setup(void)
 {
        struct pci_bus *b;
 
+       if (firmware_has_feature(FW_FEATURE_ISERIES))
+               return;
+
        list_for_each_entry(b, &pci_root_buses, node)
                pcibios_claim_one_bus(b);
 }
-#endif
 
 #ifdef CONFIG_PPC_MULTIPLATFORM
 static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
@@ -554,9 +556,8 @@ static int __init pcibios_init(void)
         */
        ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
 
-#ifdef CONFIG_PPC_ISERIES
-       iSeries_pcibios_init(); 
-#endif
+       if (firmware_has_feature(FW_FEATURE_ISERIES))
+               iSeries_pcibios_init();
 
        printk(KERN_DEBUG "PCI: Probing PCI hardware\n");
 
@@ -566,15 +567,15 @@ static int __init pcibios_init(void)
                pci_bus_add_devices(hose->bus);
        }
 
-#ifndef CONFIG_PPC_ISERIES
-       if (pci_probe_only)
-               pcibios_claim_of_setup();
-       else
-               /* FIXME: `else' will be removed when
-                  pci_assign_unassigned_resources() is able to work
-                  correctly with [partially] allocated PCI tree. */
-               pci_assign_unassigned_resources();
-#endif /* !CONFIG_PPC_ISERIES */
+       if (!firmware_has_feature(FW_FEATURE_ISERIES)) {
+               if (pci_probe_only)
+                       pcibios_claim_of_setup();
+               else
+                       /* FIXME: `else' will be removed when
+                          pci_assign_unassigned_resources() is able to work
+                          correctly with [partially] allocated PCI tree. */
+                       pci_assign_unassigned_resources();
+       }
 
        /* Call machine dependent final fixup */
        if (ppc_md.pcibios_fixup)
@@ -586,8 +587,9 @@ static int __init pcibios_init(void)
                printk(KERN_DEBUG "ISA bridge at %s\n", pci_name(ppc64_isabridge_dev));
 
 #ifdef CONFIG_PPC_MULTIPLATFORM
-       /* map in PCI I/O space */
-       phbs_remap_io();
+       if (!firmware_has_feature(FW_FEATURE_ISERIES))
+               /* map in PCI I/O space */
+               phbs_remap_io();
 #endif
 
        printk(KERN_DEBUG "PCI: Probing PCI hardware done\n");
@@ -637,13 +639,13 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
  */
 int pci_domain_nr(struct pci_bus *bus)
 {
-#ifdef CONFIG_PPC_ISERIES
-       return 0;
-#else
-       struct pci_controller *hose = pci_bus_to_host(bus);
+       if (firmware_has_feature(FW_FEATURE_ISERIES))
+               return 0;
+       else {
+               struct pci_controller *hose = pci_bus_to_host(bus);
 
-       return hose->global_number;
-#endif
+               return hose->global_number;
+       }
 }
 
 EXPORT_SYMBOL(pci_domain_nr);
@@ -651,12 +653,12 @@ EXPORT_SYMBOL(pci_domain_nr);
 /* Decide whether to display the domain number in /proc */
 int pci_proc_domain(struct pci_bus *bus)
 {
-#ifdef CONFIG_PPC_ISERIES
-       return 0;
-#else
-       struct pci_controller *hose = pci_bus_to_host(bus);
-       return hose->buid;
-#endif
+       if (firmware_has_feature(FW_FEATURE_ISERIES))
+               return 0;
+       else {
+               struct pci_controller *hose = pci_bus_to_host(bus);
+               return hose->buid;
+       }
 }
 
 /*
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 a127a1e3c0976aea0134de07ce2c6d3d1f4d0ba6..7b2f6452ba7252caa11c377553392446d44c02e0 100644 (file)
@@ -424,7 +424,7 @@ void show_regs(struct pt_regs * regs)
        printk("NIP: "REG" LR: "REG" CTR: "REG"\n",
               regs->nip, regs->link, regs->ctr);
        printk("REGS: %p TRAP: %04lx   %s  (%s)\n",
-              regs, regs->trap, print_tainted(), system_utsname.release);
+              regs, regs->trap, print_tainted(), init_utsname()->release);
        printk("MSR: "REG" ", regs->msr);
        printbits(regs->msr, msr_bits);
        printk("  CR: %08lX  XER: %08lX\n", regs->ccr, regs->xer);
index dea75d73f9831eb8c5d0a539374212dfb2b6472f..975102a020d96e9d95bc5f747da348fa1fdc5ebd 100644 (file)
@@ -526,9 +526,7 @@ static void do_syscall_trace(void)
 
 void do_syscall_trace_enter(struct pt_regs *regs)
 {
-#ifdef CONFIG_PPC64
        secure_computing(regs->gpr[0]);
-#endif
 
        if (test_thread_flag(TIF_SYSCALL_TRACE)
            && (current->ptrace & PT_PTRACED))
@@ -548,12 +546,8 @@ void do_syscall_trace_enter(struct pt_regs *regs)
 
 void do_syscall_trace_leave(struct pt_regs *regs)
 {
-#ifdef CONFIG_PPC32
-       secure_computing(regs->gpr[0]);
-#endif
-
        if (unlikely(current->audit_context))
-               audit_syscall_exit((regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
+               audit_syscall_exit((regs->ccr&0x10000000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
                                   regs->result);
 
        if ((test_thread_flag(TIF_SYSCALL_TRACE)
@@ -561,8 +555,3 @@ void do_syscall_trace_leave(struct pt_regs *regs)
            && (current->ptrace & PT_PTRACED))
                do_syscall_trace();
 }
-
-#ifdef CONFIG_PPC32
-EXPORT_SYMBOL(do_syscall_trace_enter);
-EXPORT_SYMBOL(do_syscall_trace_leave);
-#endif
index 0af3fc1bdcc929fd37a457d6c05ef1521bf5ab0d..89cfaf49d3de8aa3ae8b53cd878ee574929d0be1 100644 (file)
@@ -442,31 +442,6 @@ void __init smp_setup_cpu_maps(void)
 }
 #endif /* CONFIG_SMP */
 
-int __initdata do_early_xmon;
-#ifdef CONFIG_XMON
-extern int xmon_no_auto_backtrace;
-
-static int __init early_xmon(char *p)
-{
-       /* ensure xmon is enabled */
-       if (p) {
-               if (strncmp(p, "on", 2) == 0)
-                       xmon_init(1);
-               if (strncmp(p, "off", 3) == 0)
-                       xmon_init(0);
-               if (strncmp(p, "nobt", 4) == 0)
-                       xmon_no_auto_backtrace = 1;
-               if (strncmp(p, "early", 5) != 0)
-                       return 0;
-       }
-       xmon_init(1);
-       do_early_xmon = 1;
-
-       return 0;
-}
-early_param("xmon", early_xmon);
-#endif
-
 static __init int add_pcspkr(void)
 {
        struct device_node *np;
index 79a17795d17bd5bfba19c61da9bf2a61bddef2d1..191d0ab0922227908db8dc6fc3b0fefa53ed876d 100644 (file)
@@ -238,12 +238,11 @@ void __init setup_arch(char **cmdline_p)
 
        smp_setup_cpu_maps();
 
-#ifdef CONFIG_XMON_DEFAULT
-       xmon_init(1);
-#endif
        /* Register early console */
        register_early_udbg_console();
 
+       xmon_setup();
+
 #if defined(CONFIG_KGDB)
        if (ppc_md.kgdb_map_scc)
                ppc_md.kgdb_map_scc();
@@ -280,9 +279,6 @@ void __init setup_arch(char **cmdline_p)
        init_mm.end_data = (unsigned long) _edata;
        init_mm.brk = klimit;
 
-       if (do_early_xmon)
-               debugger(NULL);
-
        /* set up the bootmem stuff with available memory */
        do_init_bootmem();
        if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);
index 962ad5ebc7678aad6df97f8640f6fb95a3261ac2..4b2e32eab9dc3e6b50bea7ffdf52fcdcb229492d 100644 (file)
@@ -390,19 +390,15 @@ void __init setup_system(void)
         */
        find_legacy_serial_ports();
 
-       /*
-        * Initialize xmon
-        */
-#ifdef CONFIG_XMON_DEFAULT
-       xmon_init(1);
-#endif
        /*
         * Register early console
         */
        register_early_udbg_console();
 
-       if (do_early_xmon)
-               debugger(NULL);
+       /*
+        * Initialize xmon
+        */
+       xmon_setup();
 
        check_smt_enabled();
        smp_setup_cpu_maps();
@@ -414,7 +410,7 @@ void __init setup_system(void)
        smp_release_cpus();
 #endif
 
-       printk("Starting Linux PPC64 %s\n", system_utsname.version);
+       printk("Starting Linux PPC64 %s\n", init_utsname()->version);
 
        printk("-----------------------------------------------------\n");
        printk("ppc64_pft_size                = 0x%lx\n", ppc64_pft_size);
index 5e391fc253407fcfa8b712363d74d46bb99ee7c5..d15c33e95959998dde17fdbd053244f0ecfa80f7 100644 (file)
@@ -69,16 +69,20 @@ struct readdir_callback32 {
 };
 
 static int fillonedir(void * __buf, const char * name, int namlen,
-                                 off_t offset, ino_t ino, unsigned int d_type)
+                                 off_t offset, u64 ino, unsigned int d_type)
 {
        struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf;
        struct old_linux_dirent32 __user * dirent;
+       ino_t d_ino;
 
        if (buf->count)
                return -EINVAL;
+       d_ino = ino;
+       if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+               return -EOVERFLOW;
        buf->count++;
        dirent = buf->dirent;
-       put_user(ino, &dirent->d_ino);
+       put_user(d_ino, &dirent->d_ino);
        put_user(offset, &dirent->d_offset);
        put_user(namlen, &dirent->d_namlen);
        copy_to_user(dirent->d_name, name, namlen);
@@ -120,15 +124,20 @@ asmlinkage long ppc32_select(u32 n, compat_ulong_t __user *inp,
 
 int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
 {
+       compat_ino_t ino;
        long err;
 
        if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) ||
            !new_valid_dev(stat->rdev))
                return -EOVERFLOW;
 
+       ino = stat->ino;
+       if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
+               return -EOVERFLOW;
+
        err  = access_ok(VERIFY_WRITE, statbuf, sizeof(*statbuf)) ? 0 : -EFAULT;
        err |= __put_user(new_encode_dev(stat->dev), &statbuf->st_dev);
-       err |= __put_user(stat->ino, &statbuf->st_ino);
+       err |= __put_user(ino, &statbuf->st_ino);
        err |= __put_user(stat->mode, &statbuf->st_mode);
        err |= __put_user(stat->nlink, &statbuf->st_nlink);
        err |= __put_user(stat->uid, &statbuf->st_uid);
index 9b69d99a910381237791d5e7d0dd9d7c5219aadc..d358866b880f25012aadf35a5e6340dd233ae801 100644 (file)
@@ -260,7 +260,7 @@ long ppc_newuname(struct new_utsname __user * name)
        int err = 0;
 
        down_read(&uts_sem);
-       if (copy_to_user(name, &system_utsname, sizeof(*name)))
+       if (copy_to_user(name, utsname(), sizeof(*name)))
                err = -EFAULT;
        up_read(&uts_sem);
        if (!err)
@@ -273,7 +273,7 @@ int sys_uname(struct old_utsname __user *name)
        int err = 0;
        
        down_read(&uts_sem);
-       if (copy_to_user(name, &system_utsname, sizeof(*name)))
+       if (copy_to_user(name, utsname(), sizeof(*name)))
                err = -EFAULT;
        up_read(&uts_sem);
        if (!err)
@@ -289,19 +289,19 @@ int sys_olduname(struct oldold_utsname __user *name)
                return -EFAULT;
   
        down_read(&uts_sem);
-       error = __copy_to_user(&name->sysname, &system_utsname.sysname,
+       error = __copy_to_user(&name->sysname, &utsname()->sysname,
                               __OLD_UTS_LEN);
        error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
-       error |= __copy_to_user(&name->nodename, &system_utsname.nodename,
+       error |= __copy_to_user(&name->nodename, &utsname()->nodename,
                                __OLD_UTS_LEN);
        error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
-       error |= __copy_to_user(&name->release, &system_utsname.release,
+       error |= __copy_to_user(&name->release, &utsname()->release,
                                __OLD_UTS_LEN);
        error |= __put_user(0, name->release + __OLD_UTS_LEN);
-       error |= __copy_to_user(&name->version, &system_utsname.version,
+       error |= __copy_to_user(&name->version, &utsname()->version,
                                __OLD_UTS_LEN);
        error |= __put_user(0, name->version + __OLD_UTS_LEN);
-       error |= __copy_to_user(&name->machine, &system_utsname.machine,
+       error |= __copy_to_user(&name->machine, &utsname()->machine,
                                __OLD_UTS_LEN);
        error |= override_machine(name->machine);
        up_read(&uts_sem);
index 406f308ddeaddf2dda54c6f75ae656f2b9e159cf..d45a168bdacaaff0dc7092e50772102046566eb1 100644 (file)
@@ -25,8 +25,8 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices);
 /* SMT stuff */
 
 #ifdef CONFIG_PPC_MULTIPLATFORM
-/* default to snooze disabled */
-DEFINE_PER_CPU(unsigned long, smt_snooze_delay);
+/* Time in microseconds we delay before sleeping in the idle loop */
+DEFINE_PER_CPU(unsigned long, smt_snooze_delay) = { 100 };
 
 static ssize_t store_smt_snooze_delay(struct sys_device *dev, const char *buf,
                                      size_t count)
index 8b278d85ca4ed24b44f8b93f33257f79f6d3294c..85b9244a098c79d76373e4d75eef1cbe54a8a395 100644 (file)
@@ -1041,6 +1041,48 @@ void __init time_init(void)
        set_dec(tb_ticks_per_jiffy);
 }
 
+#ifdef CONFIG_RTC_CLASS
+static int set_rtc_class_time(struct rtc_time *tm)
+{
+       int err;
+       struct class_device *class_dev =
+               rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
+
+       if (class_dev == NULL)
+               return -ENODEV;
+
+       err = rtc_set_time(class_dev, tm);
+
+       rtc_class_close(class_dev);
+
+       return 0;
+}
+
+static void get_rtc_class_time(struct rtc_time *tm)
+{
+       int err;
+       struct class_device *class_dev =
+               rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
+
+       if (class_dev == NULL)
+               return;
+
+       err = rtc_read_time(class_dev, tm);
+
+       rtc_class_close(class_dev);
+
+       return;
+}
+
+int __init rtc_class_hookup(void)
+{
+       ppc_md.get_rtc_time = get_rtc_class_time;
+       ppc_md.set_rtc_time = set_rtc_class_time;
+
+       return 0;
+}
+#endif /* CONFIG_RTC_CLASS */
+
 
 #define FEBRUARY       2
 #define        STARTOFTIME     1970
index 02665a02130d1730a918f2a3f43e1f170a4bca4c..cb0e8d46c3e8fa383f2be4f9d23cc1428ee39e09 100644 (file)
@@ -132,6 +132,14 @@ SECTIONS
                *(__ftr_fixup)
                __stop___ftr_fixup = .;
        }
+#ifdef CONFIG_PPC64
+       . = ALIGN(8);
+       __fw_ftr_fixup : {
+               __start___fw_ftr_fixup = .;
+               *(__fw_ftr_fixup)
+               __stop___fw_ftr_fixup = .;
+       }
+#endif
 
        . = ALIGN(PAGE_SIZE);
        .init.ramfs : {
index 336dd191f768c1a8e4949cf9f928ed3f6d21fcae..a0360ae10d0ccd5db00a1a0ff77b6bde74bd1629 100644 (file)
@@ -14,9 +14,15 @@ endif
 obj-$(CONFIG_PPC64)    += checksum_64.o copypage_64.o copyuser_64.o \
                           memcpy_64.o usercopy_64.o mem_64.o string.o \
                           strcase.o
+obj-$(CONFIG_QUICC_ENGINE) += rheap.o
 obj-$(CONFIG_XMON)     += sstep.o
 
 ifeq ($(CONFIG_PPC64),y)
 obj-$(CONFIG_SMP)      += locks.o
 obj-$(CONFIG_DEBUG_KERNEL) += sstep.o
 endif
+
+# Temporary hack until we have migrated to asm-powerpc
+ifeq ($(CONFIG_PPC_MERGE),y)
+obj-$(CONFIG_CPM2)     += rheap.o
+endif
index 31e511856dc58bc2b819e80c32a35840db5bd9ca..57bf991ccd6e11751cf4b37c5f4548ac83e55aba 100644 (file)
@@ -423,17 +423,21 @@ void *rh_detach_region(rh_info_t * info, void *start, int size)
        return (void *)s;
 }
 
-void *rh_alloc(rh_info_t * info, int size, const char *owner)
+void *rh_alloc_align(rh_info_t * info, int size, int alignment, const char *owner)
 {
        struct list_head *l;
        rh_block_t *blk;
        rh_block_t *newblk;
        void *start;
 
-       /* Validate size */
-       if (size <= 0)
+       /* Validate size, (must be power of two) */
+       if (size <= 0 || (alignment & (alignment - 1)) != 0)
                return ERR_PTR(-EINVAL);
 
+       /* given alignment larger that default rheap alignment */
+       if (alignment > info->alignment)
+               size += alignment - 1;
+
        /* Align to configured alignment */
        size = (size + (info->alignment - 1)) & ~(info->alignment - 1);
 
@@ -476,15 +480,27 @@ void *rh_alloc(rh_info_t * info, int size, const char *owner)
 
        attach_taken_block(info, newblk);
 
+       /* for larger alignment return fixed up pointer  */
+       /* this is no problem with the deallocator since */
+       /* we scan for pointers that lie in the blocks   */
+       if (alignment > info->alignment)
+               start = (void *)(((unsigned long)start + alignment - 1) &
+                               ~(alignment - 1));
+
        return start;
 }
 
+void *rh_alloc(rh_info_t * info, int size, const char *owner)
+{
+       return rh_alloc_align(info, size, info->alignment, owner);
+}
+
 /* allocate at precisely the given address */
 void *rh_alloc_fixed(rh_info_t * info, void *start, int size, const char *owner)
 {
        struct list_head *l;
        rh_block_t *blk, *newblk1, *newblk2;
-       unsigned long s, e, m, bs, be;
+       unsigned long s, e, m, bs = 0, be = 0;
 
        /* Validate size */
        if (size <= 0)
index 754143e8936bd4c528ae6bfccaba166a761ee8b0..29bc9126241b1d9893acf6d51024a6f6797efa19 100644 (file)
@@ -11,3 +11,6 @@ obj-$(CONFIG_MATH_EMULATION)  += fabs.o fadd.o fadds.o fcmpo.o fcmpu.o \
                                        mcrfs.o mffs.o mtfsb0.o mtfsb1.o \
                                        mtfsf.o mtfsfi.o stfiwx.o stfs.o \
                                        udivmodti4.o
+
+CFLAGS_fabs.o = -fno-builtin-fabs
+CFLAGS_math.o = -fno-builtin-fabs
index b1da0316549601745d6c21e49f6fd78098e766e0..ac64f4aaa5091b0fa48246eff049318303dc7bc2 100644 (file)
 #include <asm/iommu.h>
 #include <asm/abs_addr.h>
 #include <asm/vdso.h>
+#include <asm/firmware.h>
 
 #include "mmu_decl.h"
 
 unsigned long ioremap_bot = IMALLOC_BASE;
 static unsigned long phbs_io_bot = PHBS_IO_BASE;
 
-#ifdef CONFIG_PPC_ISERIES
-
-void __iomem *ioremap(unsigned long addr, unsigned long size)
-{
-       return (void __iomem *)addr;
-}
-
-extern void __iomem *__ioremap(unsigned long addr, unsigned long size,
-                      unsigned long flags)
-{
-       return (void __iomem *)addr;
-}
-
-void iounmap(volatile void __iomem *addr)
-{
-       return;
-}
-
-#else
-
 /*
  * map_io_page currently only called by __ioremap
  * map_io_page adds an entry to the ioremap page table
@@ -161,6 +142,9 @@ void __iomem * __ioremap(unsigned long addr, unsigned long size,
        unsigned long pa, ea;
        void __iomem *ret;
 
+       if (firmware_has_feature(FW_FEATURE_ISERIES))
+               return (void __iomem *)addr;
+
        /*
         * Choose an address to map it to.
         * Once the imalloc system is running, we use it.
@@ -255,6 +239,9 @@ void iounmap(volatile void __iomem *token)
 {
        void *addr;
 
+       if (firmware_has_feature(FW_FEATURE_ISERIES))
+               return;
+
        if (!mem_init_done)
                return;
        
@@ -315,8 +302,6 @@ int iounmap_explicit(volatile void __iomem *start, unsigned long size)
        return 0;
 }
 
-#endif
-
 EXPORT_SYMBOL(ioremap);
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(iounmap);
index dbc1abbde0381f6a821a2d87fc1b55ab0b00deda..b10e4707d7c1396f858f43ba4f9f30eb6d233072 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/page.h>
 #include <asm/mmu.h>
 #include <asm/pgtable.h>
+#include <asm/firmware.h>
 
 /* void slb_allocate_realmode(unsigned long ea);
  *
@@ -183,6 +184,7 @@ slb_finish_load:
         * dont have any LRU information to help us choose a slot.
         */
 #ifdef CONFIG_PPC_ISERIES
+BEGIN_FW_FTR_SECTION
        /*
         * On iSeries, the "bolted" stack segment can be cast out on
         * shared processor switch so we need to check for a miss on
@@ -194,6 +196,7 @@ slb_finish_load:
        li      r10,SLB_NUM_BOLTED-1    /* Stack goes in last bolted slot */
        cmpld   r9,r3
        beq     3f
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif /* CONFIG_PPC_ISERIES */
 
        ld      r10,PACASTABRR(r13)
index 75f57bc96b404416480d410a537eccfcdbcfe4b6..b4278cfd1f80cccb5596f29b6c5068961aad06c2 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/sched.h>
 #include <asm/processor.h>
 #include <asm/uaccess.h>
+#include <asm/compat.h>
 
 #define STACK_SP(STACK)                *(STACK)
 
@@ -26,8 +27,9 @@
 static unsigned int user_getsp32(unsigned int sp, int is_first)
 {
        unsigned int stack_frame[2];
+       void __user *p = compat_ptr(sp);
 
-       if (!access_ok(VERIFY_READ, sp, sizeof(stack_frame)))
+       if (!access_ok(VERIFY_READ, p, sizeof(stack_frame)))
                return 0;
 
        /*
@@ -35,8 +37,7 @@ static unsigned int user_getsp32(unsigned int sp, int is_first)
         * which means that we've done all that we can do from
         * interrupt context.
         */
-       if (__copy_from_user_inatomic(stack_frame, (void *)(long)sp,
-                                       sizeof(stack_frame)))
+       if (__copy_from_user_inatomic(stack_frame, p, sizeof(stack_frame)))
                return 0;
 
        if (!is_first)
@@ -54,10 +55,10 @@ static unsigned long user_getsp64(unsigned long sp, int is_first)
 {
        unsigned long stack_frame[3];
 
-       if (!access_ok(VERIFY_READ, sp, sizeof(stack_frame)))
+       if (!access_ok(VERIFY_READ, (void __user *)sp, sizeof(stack_frame)))
                return 0;
 
-       if (__copy_from_user_inatomic(stack_frame, (void *)sp,
+       if (__copy_from_user_inatomic(stack_frame, (void __user *)sp,
                                        sizeof(stack_frame)))
                return 0;
 
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
diff --git a/arch/powerpc/platforms/82xx/Kconfig b/arch/powerpc/platforms/82xx/Kconfig
new file mode 100644 (file)
index 0000000..47d841e
--- /dev/null
@@ -0,0 +1,21 @@
+menu "Platform support"
+       depends on PPC_82xx
+
+choice
+       prompt "Machine Type"
+       default MPC82xx_ADS
+
+config MPC82xx_ADS
+       bool "Freescale MPC82xx ADS"
+       select DEFAULT_UIMAGE
+       select PQ2ADS
+       select 8272
+       select 8260
+       select CPM2
+       select FSL_SOC
+       help
+         This option enables support for the MPC8272 ADS board
+
+endchoice
+
+endmenu
diff --git a/arch/powerpc/platforms/82xx/Makefile b/arch/powerpc/platforms/82xx/Makefile
new file mode 100644 (file)
index 0000000..d9fd4c8
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the PowerPC 82xx linux kernel.
+#
+obj-$(CONFIG_PPC_82xx) += mpc82xx.o
+obj-$(CONFIG_MPC82xx_ADS) += mpc82xx_ads.o
diff --git a/arch/powerpc/platforms/82xx/m82xx_pci.h b/arch/powerpc/platforms/82xx/m82xx_pci.h
new file mode 100644 (file)
index 0000000..9cd8893
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef _PPC_KERNEL_M82XX_PCI_H
+#define _PPC_KERNEL_M82XX_PCI_H
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/m8260_pci.h>
+
+#define SIU_INT_IRQ1   ((uint)0x13 + CPM_IRQ_OFFSET)
+
+#ifndef _IO_BASE
+#define _IO_BASE isa_io_base
+#endif
+
+#endif                         /* _PPC_KERNEL_M8260_PCI_H */
diff --git a/arch/powerpc/platforms/82xx/mpc82xx.c b/arch/powerpc/platforms/82xx/mpc82xx.c
new file mode 100644 (file)
index 0000000..89d702d
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * MPC82xx setup and early boot code plus other random bits.
+ *
+ * Author: Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * Copyright (c) 2006 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/initrd.h>
+#include <linux/module.h>
+#include <linux/fsl_devices.h>
+#include <linux/fs_uart_pd.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/atomic.h>
+#include <asm/time.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/bootinfo.h>
+#include <asm/pci-bridge.h>
+#include <asm/mpc8260.h>
+#include <asm/irq.h>
+#include <mm/mmu_decl.h>
+#include <asm/prom.h>
+#include <asm/cpm2.h>
+#include <asm/udbg.h>
+#include <asm/i8259.h>
+#include <linux/fs_enet_pd.h>
+
+#include <sysdev/fsl_soc.h>
+#include <sysdev/cpm2_pic.h>
+
+#include "pq2ads_pd.h"
+
+static int __init get_freq(char *name, unsigned long *val)
+{
+       struct device_node *cpu;
+       unsigned int *fp;
+       int found = 0;
+
+       /* The cpu node should have timebase and clock frequency properties */
+       cpu = of_find_node_by_type(NULL, "cpu");
+
+       if (cpu) {
+               fp = (unsigned int *)get_property(cpu, name, NULL);
+               if (fp) {
+                       found = 1;
+                       *val = *fp++;
+               }
+
+               of_node_put(cpu);
+       }
+
+       return found;
+}
+
+void __init m82xx_calibrate_decr(void)
+{
+       ppc_tb_freq = 125000000;
+       if (!get_freq("bus-frequency", &ppc_tb_freq)) {
+               printk(KERN_ERR "WARNING: Estimating decrementer frequency "
+                               "(not found)\n");
+       }
+       ppc_tb_freq /= 4;
+       ppc_proc_freq = 1000000000;
+       if (!get_freq("clock-frequency", &ppc_proc_freq))
+               printk(KERN_ERR "WARNING: Estimating processor frequency"
+                               "(not found)\n");
+}
+
+void mpc82xx_ads_show_cpuinfo(struct seq_file *m)
+{
+       uint pvid, svid, phid1;
+       uint memsize = total_memory;
+
+       pvid = mfspr(SPRN_PVR);
+       svid = mfspr(SPRN_SVR);
+
+       seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n");
+       seq_printf(m, "Machine\t\t: %s\n", CPUINFO_MACHINE);
+       seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
+       seq_printf(m, "SVR\t\t: 0x%x\n", svid);
+
+       /* Display cpu Pll setting */
+       phid1 = mfspr(SPRN_HID1);
+       seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
+
+       /* Display the amount of memory */
+       seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
+}
diff --git a/arch/powerpc/platforms/82xx/mpc82xx_ads.c b/arch/powerpc/platforms/82xx/mpc82xx_ads.c
new file mode 100644 (file)
index 0000000..4276f08
--- /dev/null
@@ -0,0 +1,661 @@
+/*
+ * MPC82xx_ads setup and early boot code plus other random bits.
+ *
+ * Author: Vitaly Bordug <vbordug@ru.mvista.com>
+ * m82xx_restart fix by Wade Farnsworth <wfarnsworth@mvista.com>
+ *
+ * Copyright (c) 2006 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/initrd.h>
+#include <linux/module.h>
+#include <linux/fsl_devices.h>
+#include <linux/fs_uart_pd.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/atomic.h>
+#include <asm/time.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/bootinfo.h>
+#include <asm/pci-bridge.h>
+#include <asm/mpc8260.h>
+#include <asm/irq.h>
+#include <mm/mmu_decl.h>
+#include <asm/prom.h>
+#include <asm/cpm2.h>
+#include <asm/udbg.h>
+#include <asm/i8259.h>
+#include <linux/fs_enet_pd.h>
+
+#include <sysdev/fsl_soc.h>
+#include <../sysdev/cpm2_pic.h>
+
+#include "pq2ads_pd.h"
+
+#ifdef CONFIG_PCI
+static uint pci_clk_frq;
+static struct {
+       unsigned long *pci_int_stat_reg;
+       unsigned long *pci_int_mask_reg;
+} pci_regs;
+
+static unsigned long pci_int_base;
+static struct irq_host *pci_pic_host;
+static struct device_node *pci_pic_node;
+#endif
+
+static void __init mpc82xx_ads_pic_init(void)
+{
+       struct device_node *np = of_find_compatible_node(NULL, "cpm-pic", "CPM2");
+       struct resource r;
+       cpm2_map_t *cpm_reg;
+
+       if (np == NULL) {
+               printk(KERN_ERR "PIC init: can not find cpm-pic node\n");
+               return;
+       }
+       if (of_address_to_resource(np, 0, &r)) {
+               printk(KERN_ERR "PIC init: invalid resource\n");
+               of_node_put(np);
+               return;
+       }
+       cpm2_pic_init(np);
+       of_node_put(np);
+
+       /* Initialize the default interrupt mapping priorities,
+        * in case the boot rom changed something on us.
+        */
+       cpm_reg = (cpm2_map_t *) ioremap(get_immrbase(), sizeof(cpm2_map_t));
+       cpm_reg->im_intctl.ic_siprr = 0x05309770;
+       iounmap(cpm_reg);
+#ifdef CONFIG_PCI
+       /* Initialize stuff for the 82xx CPLD IC and install demux  */
+       m82xx_pci_init_irq();
+#endif
+}
+
+static void init_fcc1_ioports(struct fs_platform_info *fpi)
+{
+       struct io_port *io;
+       u32 tempval;
+       cpm2_map_t *immap = ioremap(get_immrbase(), sizeof(cpm2_map_t));
+       struct device_node *np;
+       struct resource r;
+       u32 *bcsr;
+
+       np = of_find_node_by_type(NULL, "memory");
+       if (!np) {
+               printk(KERN_INFO "No memory node in device tree\n");
+               return;
+       }
+       if (of_address_to_resource(np, 1, &r)) {
+               printk(KERN_INFO "No memory reg property [1] in devicetree\n");
+               return;
+       }
+       of_node_put(np);
+       bcsr = ioremap(r.start + 4, sizeof(u32));
+       io = &immap->im_ioport;
+
+       /* Enable the PHY */
+       clrbits32(bcsr, BCSR1_FETHIEN);
+       setbits32(bcsr, BCSR1_FETH_RST);
+
+       /* FCC1 pins are on port A/C. */
+       /* Configure port A and C pins for FCC1 Ethernet. */
+
+       tempval = in_be32(&io->iop_pdira);
+       tempval &= ~PA1_DIRA0;
+       tempval |= PA1_DIRA1;
+       out_be32(&io->iop_pdira, tempval);
+
+       tempval = in_be32(&io->iop_psora);
+       tempval &= ~PA1_PSORA0;
+       tempval |= PA1_PSORA1;
+       out_be32(&io->iop_psora, tempval);
+
+       setbits32(&io->iop_ppara, PA1_DIRA0 | PA1_DIRA1);
+
+       /* Alter clocks */
+       tempval = PC_CLK(fpi->clk_tx - 8) | PC_CLK(fpi->clk_rx - 8);
+
+       clrbits32(&io->iop_psorc, tempval);
+       clrbits32(&io->iop_pdirc, tempval);
+       setbits32(&io->iop_pparc, tempval);
+
+       cpm2_clk_setup(CPM_CLK_FCC1, fpi->clk_rx, CPM_CLK_RX);
+       cpm2_clk_setup(CPM_CLK_FCC1, fpi->clk_tx, CPM_CLK_TX);
+
+       iounmap(bcsr);
+       iounmap(immap);
+}
+
+static void init_fcc2_ioports(struct fs_platform_info *fpi)
+{
+       cpm2_map_t *immap = ioremap(get_immrbase(), sizeof(cpm2_map_t));
+       struct device_node *np;
+       struct resource r;
+       u32 *bcsr;
+
+       struct io_port *io;
+       u32 tempval;
+
+       np = of_find_node_by_type(NULL, "memory");
+       if (!np) {
+               printk(KERN_INFO "No memory node in device tree\n");
+               return;
+       }
+       if (of_address_to_resource(np, 1, &r)) {
+               printk(KERN_INFO "No memory reg property [1] in devicetree\n");
+               return;
+       }
+       of_node_put(np);
+       io = &immap->im_ioport;
+       bcsr = ioremap(r.start + 12, sizeof(u32));
+
+       /* Enable the PHY */
+       clrbits32(bcsr, BCSR3_FETHIEN2);
+       setbits32(bcsr, BCSR3_FETH2_RST);
+
+       /* FCC2 are port B/C. */
+       /* Configure port A and C pins for FCC2 Ethernet. */
+
+       tempval = in_be32(&io->iop_pdirb);
+       tempval &= ~PB2_DIRB0;
+       tempval |= PB2_DIRB1;
+       out_be32(&io->iop_pdirb, tempval);
+
+       tempval = in_be32(&io->iop_psorb);
+       tempval &= ~PB2_PSORB0;
+       tempval |= PB2_PSORB1;
+       out_be32(&io->iop_psorb, tempval);
+
+       setbits32(&io->iop_pparb, PB2_DIRB0 | PB2_DIRB1);
+
+       tempval = PC_CLK(fpi->clk_tx - 8) | PC_CLK(fpi->clk_rx - 8);
+
+       /* Alter clocks */
+       clrbits32(&io->iop_psorc, tempval);
+       clrbits32(&io->iop_pdirc, tempval);
+       setbits32(&io->iop_pparc, tempval);
+
+       cpm2_clk_setup(CPM_CLK_FCC2, fpi->clk_rx, CPM_CLK_RX);
+       cpm2_clk_setup(CPM_CLK_FCC2, fpi->clk_tx, CPM_CLK_TX);
+
+       iounmap(bcsr);
+       iounmap(immap);
+}
+
+void init_fcc_ioports(struct fs_platform_info *fpi)
+{
+       int fcc_no = fs_get_fcc_index(fpi->fs_no);
+
+       switch (fcc_no) {
+       case 0:
+               init_fcc1_ioports(fpi);
+               break;
+       case 1:
+               init_fcc2_ioports(fpi);
+               break;
+       default:
+               printk(KERN_ERR "init_fcc_ioports: invalid FCC number\n");
+               return;
+       }
+}
+
+static void init_scc1_uart_ioports(struct fs_uart_platform_info *data)
+{
+       cpm2_map_t *immap = ioremap(get_immrbase(), sizeof(cpm2_map_t));
+
+       /* SCC1 is only on port D */
+       setbits32(&immap->im_ioport.iop_ppard, 0x00000003);
+       clrbits32(&immap->im_ioport.iop_psord, 0x00000001);
+       setbits32(&immap->im_ioport.iop_psord, 0x00000002);
+       clrbits32(&immap->im_ioport.iop_pdird, 0x00000001);
+       setbits32(&immap->im_ioport.iop_pdird, 0x00000002);
+
+       clrbits32(&immap->im_cpmux.cmx_scr, (0x00000007 << (4 - data->clk_tx)));
+       clrbits32(&immap->im_cpmux.cmx_scr, (0x00000038 << (4 - data->clk_rx)));
+       setbits32(&immap->im_cpmux.cmx_scr,
+                 ((data->clk_tx - 1) << (4 - data->clk_tx)));
+       setbits32(&immap->im_cpmux.cmx_scr,
+                 ((data->clk_rx - 1) << (4 - data->clk_rx)));
+
+       iounmap(immap);
+}
+
+static void init_scc4_uart_ioports(struct fs_uart_platform_info *data)
+{
+       cpm2_map_t *immap = ioremap(get_immrbase(), sizeof(cpm2_map_t));
+
+       setbits32(&immap->im_ioport.iop_ppard, 0x00000600);
+       clrbits32(&immap->im_ioport.iop_psord, 0x00000600);
+       clrbits32(&immap->im_ioport.iop_pdird, 0x00000200);
+       setbits32(&immap->im_ioport.iop_pdird, 0x00000400);
+
+       clrbits32(&immap->im_cpmux.cmx_scr, (0x00000007 << (4 - data->clk_tx)));
+       clrbits32(&immap->im_cpmux.cmx_scr, (0x00000038 << (4 - data->clk_rx)));
+       setbits32(&immap->im_cpmux.cmx_scr,
+                 ((data->clk_tx - 1) << (4 - data->clk_tx)));
+       setbits32(&immap->im_cpmux.cmx_scr,
+                 ((data->clk_rx - 1) << (4 - data->clk_rx)));
+
+       iounmap(immap);
+}
+
+void init_scc_ioports(struct fs_uart_platform_info *data)
+{
+       int scc_no = fs_get_scc_index(data->fs_no);
+
+       switch (scc_no) {
+       case 0:
+               init_scc1_uart_ioports(data);
+               data->brg = data->clk_rx;
+               break;
+       case 3:
+               init_scc4_uart_ioports(data);
+               data->brg = data->clk_rx;
+               break;
+       default:
+               printk(KERN_ERR "init_scc_ioports: invalid SCC number\n");
+               return;
+       }
+}
+
+void __init m82xx_board_setup(void)
+{
+       cpm2_map_t *immap = ioremap(get_immrbase(), sizeof(cpm2_map_t));
+       struct device_node *np;
+       struct resource r;
+       u32 *bcsr;
+
+       np = of_find_node_by_type(NULL, "memory");
+       if (!np) {
+               printk(KERN_INFO "No memory node in device tree\n");
+               return;
+       }
+       if (of_address_to_resource(np, 1, &r)) {
+               printk(KERN_INFO "No memory reg property [1] in devicetree\n");
+               return;
+       }
+       of_node_put(np);
+       bcsr = ioremap(r.start + 4, sizeof(u32));
+       /* Enable the 2nd UART port */
+       clrbits32(bcsr, BCSR1_RS232_EN2);
+
+#ifdef CONFIG_SERIAL_CPM_SCC1
+       clrbits32((u32 *) & immap->im_scc[0].scc_sccm,
+                 UART_SCCM_TX | UART_SCCM_RX);
+       clrbits32((u32 *) & immap->im_scc[0].scc_gsmrl,
+                 SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+#endif
+
+#ifdef CONFIG_SERIAL_CPM_SCC2
+       clrbits32((u32 *) & immap->im_scc[1].scc_sccm,
+                 UART_SCCM_TX | UART_SCCM_RX);
+       clrbits32((u32 *) & immap->im_scc[1].scc_gsmrl,
+                 SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+#endif
+
+#ifdef CONFIG_SERIAL_CPM_SCC3
+       clrbits32((u32 *) & immap->im_scc[2].scc_sccm,
+                 UART_SCCM_TX | UART_SCCM_RX);
+       clrbits32((u32 *) & immap->im_scc[2].scc_gsmrl,
+                 SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+#endif
+
+#ifdef CONFIG_SERIAL_CPM_SCC4
+       clrbits32((u32 *) & immap->im_scc[3].scc_sccm,
+                 UART_SCCM_TX | UART_SCCM_RX);
+       clrbits32((u32 *) & immap->im_scc[3].scc_gsmrl,
+                 SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+#endif
+
+       iounmap(bcsr);
+       iounmap(immap);
+}
+
+#ifdef CONFIG_PCI
+static void m82xx_pci_mask_irq(unsigned int irq)
+{
+       int bit = irq - pci_int_base;
+
+       *pci_regs.pci_int_mask_reg |= (1 << (31 - bit));
+       return;
+}
+
+static void m82xx_pci_unmask_irq(unsigned int irq)
+{
+       int bit = irq - pci_int_base;
+
+       *pci_regs.pci_int_mask_reg &= ~(1 << (31 - bit));
+       return;
+}
+
+static void m82xx_pci_mask_and_ack(unsigned int irq)
+{
+       int bit = irq - pci_int_base;
+
+       *pci_regs.pci_int_mask_reg |= (1 << (31 - bit));
+       return;
+}
+
+static void m82xx_pci_end_irq(unsigned int irq)
+{
+       int bit = irq - pci_int_base;
+
+       *pci_regs.pci_int_mask_reg &= ~(1 << (31 - bit));
+       return;
+}
+
+struct hw_interrupt_type m82xx_pci_ic = {
+       .typename = "MPC82xx ADS PCI",
+       .name = "MPC82xx ADS PCI",
+       .enable = m82xx_pci_unmask_irq,
+       .disable = m82xx_pci_mask_irq,
+       .ack = m82xx_pci_mask_and_ack,
+       .end = m82xx_pci_end_irq,
+       .mask = m82xx_pci_mask_irq,
+       .mask_ack = m82xx_pci_mask_and_ack,
+       .unmask = m82xx_pci_unmask_irq,
+       .eoi = m82xx_pci_end_irq,
+};
+
+static void
+m82xx_pci_irq_demux(unsigned int irq, struct irq_desc *desc,
+                   struct pt_regs *regs)
+{
+       unsigned long stat, mask, pend;
+       int bit;
+
+       for (;;) {
+               stat = *pci_regs.pci_int_stat_reg;
+               mask = *pci_regs.pci_int_mask_reg;
+               pend = stat & ~mask & 0xf0000000;
+               if (!pend)
+                       break;
+               for (bit = 0; pend != 0; ++bit, pend <<= 1) {
+                       if (pend & 0x80000000)
+                               __do_IRQ(pci_int_base + bit, regs);
+               }
+       }
+}
+
+static int pci_pic_host_match(struct irq_host *h, struct device_node *node)
+{
+       return node == pci_pic_node;
+}
+
+static int pci_pic_host_map(struct irq_host *h, unsigned int virq,
+                           irq_hw_number_t hw)
+{
+       get_irq_desc(virq)->status |= IRQ_LEVEL;
+       set_irq_chip(virq, &m82xx_pci_ic);
+       return 0;
+}
+
+static void pci_host_unmap(struct irq_host *h, unsigned int virq)
+{
+       /* remove chip and handler */
+       set_irq_chip(virq, NULL);
+}
+
+static struct irq_host_ops pci_pic_host_ops = {
+       .match = pci_pic_host_match,
+       .map = pci_pic_host_map,
+       .unmap = pci_host_unmap,
+};
+
+void m82xx_pci_init_irq(void)
+{
+       int irq;
+       cpm2_map_t *immap;
+       struct device_node *np;
+       struct resource r;
+       const u32 *regs;
+       unsigned int size;
+       const u32 *irq_map;
+       int i;
+       unsigned int irq_max, irq_min;
+
+       if ((np = of_find_node_by_type(NULL, "soc")) == NULL) {
+               printk(KERN_INFO "No SOC node in device tree\n");
+               return;
+       }
+       memset(&r, 0, sizeof(r));
+       if (of_address_to_resource(np, 0, &r)) {
+               printk(KERN_INFO "No SOC reg property in device tree\n");
+               return;
+       }
+       immap = ioremap(r.start, sizeof(*immap));
+       of_node_put(np);
+
+       /* install the demultiplexer for the PCI cascade interrupt */
+       np = of_find_node_by_type(NULL, "pci");
+       if (!np) {
+               printk(KERN_INFO "No pci node on device tree\n");
+               iounmap(immap);
+               return;
+       }
+       irq_map = get_property(np, "interrupt-map", &size);
+       if ((!irq_map) || (size <= 7)) {
+               printk(KERN_INFO "No interrupt-map property of pci node\n");
+               iounmap(immap);
+               return;
+       }
+       size /= sizeof(irq_map[0]);
+       for (i = 0, irq_max = 0, irq_min = 512; i < size; i += 7, irq_map += 7) {
+               if (irq_map[5] < irq_min)
+                       irq_min = irq_map[5];
+               if (irq_map[5] > irq_max)
+                       irq_max = irq_map[5];
+       }
+       pci_int_base = irq_min;
+       irq = irq_of_parse_and_map(np, 0);
+       set_irq_chained_handler(irq, m82xx_pci_irq_demux);
+       of_node_put(np);
+       np = of_find_node_by_type(NULL, "pci-pic");
+       if (!np) {
+               printk(KERN_INFO "No pci pic node on device tree\n");
+               iounmap(immap);
+               return;
+       }
+       pci_pic_node = of_node_get(np);
+       /* PCI interrupt controller registers: status and mask */
+       regs = get_property(np, "reg", &size);
+       if ((!regs) || (size <= 2)) {
+               printk(KERN_INFO "No reg property in pci pic node\n");
+               iounmap(immap);
+               return;
+       }
+       pci_regs.pci_int_stat_reg =
+           ioremap(regs[0], sizeof(*pci_regs.pci_int_stat_reg));
+       pci_regs.pci_int_mask_reg =
+           ioremap(regs[1], sizeof(*pci_regs.pci_int_mask_reg));
+       of_node_put(np);
+       /* configure chip select for PCI interrupt controller */
+       immap->im_memctl.memc_br3 = regs[0] | 0x00001801;
+       immap->im_memctl.memc_or3 = 0xffff8010;
+       /* make PCI IRQ level sensitive */
+       immap->im_intctl.ic_siexr &= ~(1 << (14 - (irq - SIU_INT_IRQ1)));
+
+       /* mask all PCI interrupts */
+       *pci_regs.pci_int_mask_reg |= 0xfff00000;
+       iounmap(immap);
+       pci_pic_host =
+           irq_alloc_host(IRQ_HOST_MAP_LINEAR, irq_max - irq_min + 1,
+                          &pci_pic_host_ops, irq_max + 1);
+       return;
+}
+
+static int m82xx_pci_exclude_device(u_char bus, u_char devfn)
+{
+       if (bus == 0 && PCI_SLOT(devfn) == 0)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+       else
+               return PCIBIOS_SUCCESSFUL;
+}
+
+static void
+__init mpc82xx_pcibios_fixup(void)
+{
+       struct pci_dev *dev = NULL;
+
+       for_each_pci_dev(dev) {
+               pci_read_irq_line(dev);
+       }
+}
+
+void __init add_bridge(struct device_node *np)
+{
+       int len;
+       struct pci_controller *hose;
+       struct resource r;
+       const int *bus_range;
+       const void *ptr;
+
+       memset(&r, 0, sizeof(r));
+       if (of_address_to_resource(np, 0, &r)) {
+               printk(KERN_INFO "No PCI reg property in device tree\n");
+               return;
+       }
+       if (!(ptr = get_property(np, "clock-frequency", NULL))) {
+               printk(KERN_INFO "No clock-frequency property in PCI node");
+               return;
+       }
+       pci_clk_frq = *(uint *) ptr;
+       of_node_put(np);
+       bus_range = get_property(np, "bus-range", &len);
+       if (bus_range == NULL || len < 2 * sizeof(int)) {
+               printk(KERN_WARNING "Can't get bus-range for %s, assume"
+                      " bus 0\n", np->full_name);
+       }
+
+       pci_assign_all_buses = 1;
+
+       hose = pcibios_alloc_controller();
+
+       if (!hose)
+               return;
+
+       hose->arch_data = np;
+       hose->set_cfg_type = 1;
+
+       hose->first_busno = bus_range ? bus_range[0] : 0;
+       hose->last_busno = bus_range ? bus_range[1] : 0xff;
+       hose->bus_offset = 0;
+
+       hose->set_cfg_type = 1;
+
+       setup_indirect_pci(hose,
+                          r.start + offsetof(pci_cpm2_t, pci_cfg_addr),
+                          r.start + offsetof(pci_cpm2_t, pci_cfg_data));
+
+       pci_process_bridge_OF_ranges(hose, np, 1);
+}
+#endif
+
+/*
+ * Setup the architecture
+ */
+static void __init mpc82xx_ads_setup_arch(void)
+{
+#ifdef CONFIG_PCI
+       struct device_node *np;
+#endif
+
+       if (ppc_md.progress)
+               ppc_md.progress("mpc82xx_ads_setup_arch()", 0);
+       cpm2_reset();
+
+       /* Map I/O region to a 256MB BAT */
+
+       m82xx_board_setup();
+
+#ifdef CONFIG_PCI
+       ppc_md.pci_exclude_device = m82xx_pci_exclude_device;
+       for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
+               add_bridge(np);
+
+       of_node_put(np);
+       ppc_md.pci_map_irq = NULL;
+       ppc_md.pcibios_fixup = mpc82xx_pcibios_fixup;
+       ppc_md.pcibios_fixup_bus = NULL;
+#endif
+
+#ifdef  CONFIG_ROOT_NFS
+       ROOT_DEV = Root_NFS;
+#else
+       ROOT_DEV = Root_HDA1;
+#endif
+
+       if (ppc_md.progress)
+               ppc_md.progress("mpc82xx_ads_setup_arch(), finish", 0);
+}
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init mpc82xx_ads_probe(void)
+{
+       /* We always match for now, eventually we should look at
+        * the flat dev tree to ensure this is the board we are
+        * supposed to run on
+        */
+       return 1;
+}
+
+#define RMR_CSRE 0x00000001
+static void m82xx_restart(char *cmd)
+{
+       __volatile__ unsigned char dummy;
+
+       local_irq_disable();
+       ((cpm2_map_t *) cpm2_immr)->im_clkrst.car_rmr |= RMR_CSRE;
+
+       /* Clear the ME,EE,IR & DR bits in MSR to cause checkstop */
+       mtmsr(mfmsr() & ~(MSR_ME | MSR_EE | MSR_IR | MSR_DR));
+       dummy = ((cpm2_map_t *) cpm2_immr)->im_clkrst.res[0];
+       printk("Restart failed\n");
+       while (1) ;
+}
+
+static void m82xx_halt(void)
+{
+       local_irq_disable();
+       while (1) ;
+}
+
+define_machine(mpc82xx_ads)
+{
+       .name = "MPC82xx ADS",
+       .probe = mpc82xx_ads_probe,
+       .setup_arch =    mpc82xx_ads_setup_arch,
+       .init_IRQ =    mpc82xx_ads_pic_init,
+       .show_cpuinfo =    mpc82xx_ads_show_cpuinfo,
+       .get_irq =    cpm2_get_irq,
+       .calibrate_decr =    m82xx_calibrate_decr,
+       .restart = m82xx_restart,.halt = m82xx_halt,
+};
diff --git a/arch/powerpc/platforms/82xx/pq2ads.h b/arch/powerpc/platforms/82xx/pq2ads.h
new file mode 100644 (file)
index 0000000..a734821
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * PQ2/mpc8260 board-specific stuff
+ *
+ * A collection of structures, addresses, and values associated with
+ * the Freescale MPC8260ADS/MPC8266ADS-PCI boards.
+ * Copied from the RPX-Classic and SBS8260 stuff.
+ *
+ * Author: Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * Originally written by Dan Malek for Motorola MPC8260 family
+ *
+ * Copyright (c) 2001 Dan Malek <dan@embeddedalley.com>
+ * Copyright (c) 2006 MontaVista Software, Inc.
+ *
+ * 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.
+ */
+
+#ifdef __KERNEL__
+#ifndef __MACH_ADS8260_DEFS
+#define __MACH_ADS8260_DEFS
+
+#include <linux/config.h>
+
+#include <asm/ppcboot.h>
+
+/* For our show_cpuinfo hooks. */
+#define CPUINFO_VENDOR         "Freescale Semiconductor"
+#define CPUINFO_MACHINE                "PQ2 ADS PowerPC"
+
+/* Backword-compatibility stuff for the drivers */
+#define CPM_MAP_ADDR           ((uint)0xf0000000)
+#define CPM_IRQ_OFFSET 0
+
+/* The ADS8260 has 16, 32-bit wide control/status registers, accessed
+ * only on word boundaries.
+ * Not all are used (yet), or are interesting to us (yet).
+ */
+
+/* Things of interest in the CSR.
+ */
+#define BCSR0_LED0             ((uint)0x02000000)      /* 0 == on */
+#define BCSR0_LED1             ((uint)0x01000000)      /* 0 == on */
+#define BCSR1_FETHIEN          ((uint)0x08000000)      /* 0 == enable*/
+#define BCSR1_FETH_RST         ((uint)0x04000000)      /* 0 == reset */
+#define BCSR1_RS232_EN1                ((uint)0x02000000)      /* 0 ==enable */
+#define BCSR1_RS232_EN2                ((uint)0x01000000)      /* 0 ==enable */
+#define BCSR3_FETHIEN2         ((uint)0x10000000)      /* 0 == enable*/
+#define BCSR3_FETH2_RS         ((uint)0x80000000)      /* 0 == reset */
+
+/* cpm serial driver works with constants below */
+
+#define SIU_INT_SMC1           ((uint)0x04+CPM_IRQ_OFFSET)
+#define SIU_INT_SMC2i          ((uint)0x05+CPM_IRQ_OFFSET)
+#define SIU_INT_SCC1           ((uint)0x28+CPM_IRQ_OFFSET)
+#define SIU_INT_SCC2           ((uint)0x29+CPM_IRQ_OFFSET)
+#define SIU_INT_SCC3           ((uint)0x2a+CPM_IRQ_OFFSET)
+#define SIU_INT_SCC4           ((uint)0x2b+CPM_IRQ_OFFSET)
+
+void m82xx_pci_init_irq(void);
+void mpc82xx_ads_show_cpuinfo(struct seq_file*);
+void m82xx_calibrate_decr(void);
+
+#endif /* __MACH_ADS8260_DEFS */
+#endif /* __KERNEL__ */
index 5fe7b7faf45f1f8197148ea2533879d6474887d0..0975e94ac7c469bc416b0f9fab57de41e4ff0a52 100644 (file)
@@ -5,6 +5,13 @@ choice
        prompt "Machine Type"
        default MPC834x_SYS
 
+config MPC832x_MDS
+       bool "Freescale MPC832x MDS"
+       select DEFAULT_UIMAGE
+       select QUICC_ENGINE
+       help
+         This option enables support for the MPC832x MDS evaluation board.
+
 config MPC834x_SYS
        bool "Freescale MPC834x SYS"
        select DEFAULT_UIMAGE
@@ -27,6 +34,12 @@ config MPC834x_ITX
 
 endchoice
 
+config PPC_MPC832x
+       bool
+       select PPC_UDBG_16550
+       select PPC_INDIRECT_PCI
+       default y if MPC832x_MDS
+
 config MPC834x
        bool
        select PPC_UDBG_16550
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c
new file mode 100644 (file)
index 0000000..54dea9d
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
+ *
+ * Description:
+ * MPC832xE MDS board specific routines.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/initrd.h>
+
+#include <asm/system.h>
+#include <asm/atomic.h>
+#include <asm/time.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/ipic.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <sysdev/fsl_soc.h>
+#include <asm/qe.h>
+#include <asm/qe_ic.h>
+
+#include "mpc83xx.h"
+#include "mpc832x_mds.h"
+
+#undef DEBUG
+#ifdef DEBUG
+#define DBG(fmt...) udbg_printf(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+#ifndef CONFIG_PCI
+unsigned long isa_io_base = 0;
+unsigned long isa_mem_base = 0;
+#endif
+
+static u8 *bcsr_regs = NULL;
+
+u8 *get_bcsr(void)
+{
+       return bcsr_regs;
+}
+
+/* ************************************************************************
+ *
+ * Setup the architecture
+ *
+ */
+static void __init mpc832x_sys_setup_arch(void)
+{
+       struct device_node *np;
+
+       if (ppc_md.progress)
+               ppc_md.progress("mpc832x_sys_setup_arch()", 0);
+
+       np = of_find_node_by_type(NULL, "cpu");
+       if (np != 0) {
+               unsigned int *fp =
+                   (int *)get_property(np, "clock-frequency", NULL);
+               if (fp != 0)
+                       loops_per_jiffy = *fp / HZ;
+               else
+                       loops_per_jiffy = 50000000 / HZ;
+               of_node_put(np);
+       }
+
+       /* Map BCSR area */
+       np = of_find_node_by_name(NULL, "bcsr");
+       if (np != 0) {
+               struct resource res;
+
+               of_address_to_resource(np, 0, &res);
+               bcsr_regs = ioremap(res.start, res.end - res.start +1);
+               of_node_put(np);
+       }
+
+#ifdef CONFIG_PCI
+       for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
+               add_bridge(np);
+
+       ppc_md.pci_swizzle = common_swizzle;
+       ppc_md.pci_exclude_device = mpc83xx_exclude_device;
+#endif
+
+#ifdef CONFIG_QUICC_ENGINE
+       qe_reset();
+
+       if ((np = of_find_node_by_name(np, "par_io")) != NULL) {
+               par_io_init(np);
+               of_node_put(np);
+
+               for (np = NULL; (np = of_find_node_by_name(np, "ucc")) != NULL;)
+                       par_io_of_config(np);
+       }
+
+       if ((np = of_find_compatible_node(NULL, "network", "ucc_geth"))
+                       != NULL){
+               /* Reset the Ethernet PHY */
+               bcsr_regs[9] &= ~0x20;
+               udelay(1000);
+               bcsr_regs[9] |= 0x20;
+               iounmap(bcsr_regs);
+               of_node_put(np);
+       }
+
+#endif                         /* CONFIG_QUICC_ENGINE */
+
+#ifdef CONFIG_BLK_DEV_INITRD
+       if (initrd_start)
+               ROOT_DEV = Root_RAM0;
+       else
+#endif
+#ifdef  CONFIG_ROOT_NFS
+               ROOT_DEV = Root_NFS;
+#else
+               ROOT_DEV = Root_HDA1;
+#endif
+}
+
+void __init mpc832x_sys_init_IRQ(void)
+{
+
+       struct device_node *np;
+
+       np = of_find_node_by_type(NULL, "ipic");
+       if (!np)
+               return;
+
+       ipic_init(np, 0);
+
+       /* Initialize the default interrupt mapping priorities,
+        * in case the boot rom changed something on us.
+        */
+       ipic_set_default_priority();
+       of_node_put(np);
+
+#ifdef CONFIG_QUICC_ENGINE
+       np = of_find_node_by_type(NULL, "qeic");
+       if (!np)
+               return;
+
+       qe_ic_init(np, 0);
+       of_node_put(np);
+#endif                         /* CONFIG_QUICC_ENGINE */
+}
+
+#if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374)
+extern ulong ds1374_get_rtc_time(void);
+extern int ds1374_set_rtc_time(ulong);
+
+static int __init mpc832x_rtc_hookup(void)
+{
+       struct timespec tv;
+
+       ppc_md.get_rtc_time = ds1374_get_rtc_time;
+       ppc_md.set_rtc_time = ds1374_set_rtc_time;
+
+       tv.tv_nsec = 0;
+       tv.tv_sec = (ppc_md.get_rtc_time) ();
+       do_settimeofday(&tv);
+
+       return 0;
+}
+
+late_initcall(mpc832x_rtc_hookup);
+#endif
+
+/*
+ * Called very early, MMU is off, device-tree isn't unflattened
+ */
+static int __init mpc832x_sys_probe(void)
+{
+       char *model = of_get_flat_dt_prop(of_get_flat_dt_root(),
+                                         "model", NULL);
+
+       if (model == NULL)
+               return 0;
+       if (strcmp(model, "MPC8323EMDS"))
+               return 0;
+
+       DBG("%s found\n", model);
+
+       return 1;
+}
+
+define_machine(mpc832x_mds) {
+       .name           = "MPC832x MDS",
+       .probe          = mpc832x_sys_probe,
+       .setup_arch     = mpc832x_sys_setup_arch,
+       .init_IRQ       = mpc832x_sys_init_IRQ,
+       .get_irq        = ipic_get_irq,
+       .restart        = mpc83xx_restart,
+       .time_init      = mpc83xx_time_init,
+       .calibrate_decr = generic_calibrate_decr,
+       .progress       = udbg_progress,
+};
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.h b/arch/powerpc/platforms/83xx/mpc832x_mds.h
new file mode 100644 (file)
index 0000000..a495889
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
+ *
+ * Description:
+ * MPC832x MDS board specific header.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifndef __MACH_MPC832x_MDS_H__
+#define __MACH_MPC832x_MDS_H__
+
+extern u8 *get_bcsr(void);
+
+#endif                         /* __MACH_MPC832x_MDS_H__ */
index 969fbb6d8c46730b7e2da3b6912e44aa68c386ec..8c676d763bb0aecc1a47ab4ef8badba262a12707 100644 (file)
@@ -109,6 +109,10 @@ static int __init mpc834x_itx_probe(void)
        return 1;
 }
 
+#ifdef CONFIG_RTC_CLASS
+late_initcall(rtc_class_hookup);
+#endif
+
 define_machine(mpc834x_itx) {
        .name                   = "MPC834x ITX",
        .probe                  = mpc834x_itx_probe,
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
  *
diff --git a/arch/powerpc/platforms/83xx/mpc8360e_pb.c b/arch/powerpc/platforms/83xx/mpc8360e_pb.c
new file mode 100644 (file)
index 0000000..c019190
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
+ *
+ * Author: Li Yang <LeoLi@freescale.com>
+ *        Yin Olivia <Hong-hua.Yin@freescale.com>
+ *
+ * Description:
+ * MPC8360E MDS PB board specific routines.
+ *
+ * Changelog:
+ * Jun 21, 2006        Initial version
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/initrd.h>
+
+#include <asm/system.h>
+#include <asm/atomic.h>
+#include <asm/time.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/ipic.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <sysdev/fsl_soc.h>
+#include <asm/qe.h>
+#include <asm/qe_ic.h>
+
+#include "mpc83xx.h"
+
+#undef DEBUG
+#ifdef DEBUG
+#define DBG(fmt...) udbg_printf(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+#ifndef CONFIG_PCI
+unsigned long isa_io_base = 0;
+unsigned long isa_mem_base = 0;
+#endif
+
+static u8 *bcsr_regs = NULL;
+
+u8 *get_bcsr(void)
+{
+       return bcsr_regs;
+}
+
+/* ************************************************************************
+ *
+ * Setup the architecture
+ *
+ */
+static void __init mpc8360_sys_setup_arch(void)
+{
+       struct device_node *np;
+
+       if (ppc_md.progress)
+               ppc_md.progress("mpc8360_sys_setup_arch()", 0);
+
+       np = of_find_node_by_type(NULL, "cpu");
+       if (np != 0) {
+               const unsigned int *fp =
+                   get_property(np, "clock-frequency", NULL);
+               if (fp != 0)
+                       loops_per_jiffy = *fp / HZ;
+               else
+                       loops_per_jiffy = 50000000 / HZ;
+               of_node_put(np);
+       }
+
+       /* Map BCSR area */
+       np = of_find_node_by_name(NULL, "bcsr");
+       if (np != 0) {
+               struct resource res;
+
+               of_address_to_resource(np, 0, &res);
+               bcsr_regs = ioremap(res.start, res.end - res.start +1);
+               of_node_put(np);
+       }
+
+#ifdef CONFIG_PCI
+       for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
+               add_bridge(np);
+
+       ppc_md.pci_swizzle = common_swizzle;
+       ppc_md.pci_exclude_device = mpc83xx_exclude_device;
+#endif
+
+#ifdef CONFIG_QUICC_ENGINE
+       qe_reset();
+
+       if ((np = of_find_node_by_name(np, "par_io")) != NULL) {
+               par_io_init(np);
+               of_node_put(np);
+
+               for (np = NULL; (np = of_find_node_by_name(np, "ucc")) != NULL;)
+                       par_io_of_config(np);
+       }
+
+       if ((np = of_find_compatible_node(NULL, "network", "ucc_geth"))
+                       != NULL){
+               /* Reset the Ethernet PHY */
+               bcsr_regs[9] &= ~0x20;
+               udelay(1000);
+               bcsr_regs[9] |= 0x20;
+               iounmap(bcsr_regs);
+               of_node_put(np);
+       }
+
+#endif                         /* CONFIG_QUICC_ENGINE */
+
+#ifdef CONFIG_BLK_DEV_INITRD
+       if (initrd_start)
+               ROOT_DEV = Root_RAM0;
+       else
+#endif
+#ifdef  CONFIG_ROOT_NFS
+               ROOT_DEV = Root_NFS;
+#else
+               ROOT_DEV = Root_HDA1;
+#endif
+}
+
+void __init mpc8360_sys_init_IRQ(void)
+{
+
+       struct device_node *np;
+
+       np = of_find_node_by_type(NULL, "ipic");
+       if (!np)
+               return;
+
+       ipic_init(np, 0);
+
+       /* Initialize the default interrupt mapping priorities,
+        * in case the boot rom changed something on us.
+        */
+       ipic_set_default_priority();
+       of_node_put(np);
+
+#ifdef CONFIG_QUICC_ENGINE
+       np = of_find_node_by_type(NULL, "qeic");
+       if (!np)
+               return;
+
+       qe_ic_init(np, 0);
+       of_node_put(np);
+#endif                         /* CONFIG_QUICC_ENGINE */
+}
+
+#if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374)
+extern ulong ds1374_get_rtc_time(void);
+extern int ds1374_set_rtc_time(ulong);
+
+static int __init mpc8360_rtc_hookup(void)
+{
+       struct timespec tv;
+
+       ppc_md.get_rtc_time = ds1374_get_rtc_time;
+       ppc_md.set_rtc_time = ds1374_set_rtc_time;
+
+       tv.tv_nsec = 0;
+       tv.tv_sec = (ppc_md.get_rtc_time) ();
+       do_settimeofday(&tv);
+
+       return 0;
+}
+
+late_initcall(mpc8360_rtc_hookup);
+#endif
+
+/*
+ * Called very early, MMU is off, device-tree isn't unflattened
+ */
+static int __init mpc8360_sys_probe(void)
+{
+       char *model = of_get_flat_dt_prop(of_get_flat_dt_root(),
+                                         "model", NULL);
+       if (model == NULL)
+               return 0;
+       if (strcmp(model, "MPC8360EPB"))
+               return 0;
+
+       DBG("MPC8360EMDS-PB found\n");
+
+       return 1;
+}
+
+define_machine(mpc8360_sys) {
+       .name           = "MPC8360E PB",
+       .probe          = mpc8360_sys_probe,
+       .setup_arch     = mpc8360_sys_setup_arch,
+       .init_IRQ       = mpc8360_sys_init_IRQ,
+       .get_irq        = ipic_get_irq,
+       .restart        = mpc83xx_restart,
+       .time_init      = mpc83xx_time_init,
+       .calibrate_decr = generic_calibrate_decr,
+       .progress       = udbg_progress,
+};
index c3268d9877e47ab968d14d0b9718fab6307bbf41..0584f3c7e8844559d2ad15622c571fe8cf2cfb68 100644 (file)
@@ -11,6 +11,12 @@ config MPC8540_ADS
        help
          This option enables support for the MPC 8540 ADS board
 
+config MPC8560_ADS
+       bool "Freescale MPC8560 ADS"
+       select DEFAULT_UIMAGE
+       help
+         This option enables support for the MPC 8560 ADS board
+
 config MPC85xx_CDS
        bool "Freescale MPC85xx CDS"
        select DEFAULT_UIMAGE
@@ -25,6 +31,11 @@ config MPC8540
        select PPC_INDIRECT_PCI
        default y if MPC8540_ADS || MPC85xx_CDS
 
+config MPC8560
+       bool
+       select PPC_INDIRECT_PCI
+       default y if MPC8560_ADS
+
 config PPC_INDIRECT_PCI_BE
        bool
        depends on PPC_85xx
@@ -34,4 +45,14 @@ config MPIC
        bool
        default y
 
+config CPM2
+       bool
+       depends on MPC8560
+       default y
+       help
+         The CPM2 (Communications Processor Module) is a coprocessor on
+         embedded CPUs made by Motorola.  Selecting this option means that
+         you wish to build a kernel for a machine with a CPM2 coprocessor
+         on it.
+
 endmenu
index 7615aa59c78bacf6d911f2ea7e194e927f4e1b79..282f5d0d01520a4a83b78b378283e352803d7e5d 100644 (file)
@@ -3,4 +3,5 @@
 #
 obj-$(CONFIG_PPC_85xx) += misc.o pci.o
 obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o
+obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o
 obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o
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 cae6b73357d5b8ed95f5ec2e182c1ddbea02f0fc..28070e7ae5074fc36ee52929358b831ddcc8affd 100644 (file)
 #include <sysdev/fsl_soc.h>
 #include "mpc85xx.h"
 
+#ifdef CONFIG_CPM2
+#include <linux/fs_enet_pd.h>
+#include <asm/cpm2.h>
+#include <sysdev/cpm2_pic.h>
+#include <asm/fs_pd.h>
+#endif
+
 #ifndef CONFIG_PCI
 unsigned long isa_io_base = 0;
 unsigned long isa_mem_base = 0;
@@ -57,12 +64,29 @@ mpc85xx_pcibios_fixup(void)
 }
 #endif /* CONFIG_PCI */
 
+#ifdef CONFIG_CPM2
+
+static void cpm2_cascade(unsigned int irq, struct irq_desc *desc,
+                        struct pt_regs *regs)
+{
+       int cascade_irq;
+
+       while ((cascade_irq = cpm2_get_irq(regs)) >= 0) {
+               generic_handle_irq(cascade_irq, regs);
+       }
+       desc->chip->eoi(irq);
+}
+
+#endif /* CONFIG_CPM2 */
 
 void __init mpc85xx_ads_pic_init(void)
 {
        struct mpic *mpic;
        struct resource r;
        struct device_node *np = NULL;
+#ifdef CONFIG_CPM2
+       int irq;
+#endif
 
        np = of_find_node_by_type(np, "open-pic");
 
@@ -104,11 +128,103 @@ void __init mpc85xx_ads_pic_init(void)
        mpic_assign_isu(mpic, 14, r.start + 0x10100);
 
        mpic_init(mpic);
+
+#ifdef CONFIG_CPM2
+       /* Setup CPM2 PIC */
+       np = of_find_node_by_type(NULL, "cpm-pic");
+       if (np == NULL) {
+               printk(KERN_ERR "PIC init: can not find cpm-pic node\n");
+                return;
+       }
+       irq = irq_of_parse_and_map(np, 0);
+
+       cpm2_pic_init(np);
+       set_irq_chained_handler(irq, cpm2_cascade);
+#endif
 }
 
 /*
  * Setup the architecture
  */
+#ifdef CONFIG_CPM2
+void init_fcc_ioports(struct fs_platform_info *fpi)
+{
+       struct io_port *io = cpm2_map(im_ioport);
+       int fcc_no = fs_get_fcc_index(fpi->fs_no);
+       int target;
+       u32 tempval;
+
+       switch(fcc_no) {
+       case 1:
+               tempval = in_be32(&io->iop_pdirb);
+               tempval &= ~PB2_DIRB0;
+               tempval |= PB2_DIRB1;
+               out_be32(&io->iop_pdirb, tempval);
+
+               tempval = in_be32(&io->iop_psorb);
+               tempval &= ~PB2_PSORB0;
+               tempval |= PB2_PSORB1;
+               out_be32(&io->iop_psorb, tempval);
+
+               tempval = in_be32(&io->iop_pparb);
+               tempval |= (PB2_DIRB0 | PB2_DIRB1);
+               out_be32(&io->iop_pparb, tempval);
+
+               target = CPM_CLK_FCC2;
+               break;
+       case 2:
+               tempval = in_be32(&io->iop_pdirb);
+               tempval &= ~PB3_DIRB0;
+               tempval |= PB3_DIRB1;
+               out_be32(&io->iop_pdirb, tempval);
+
+               tempval = in_be32(&io->iop_psorb);
+               tempval &= ~PB3_PSORB0;
+               tempval |= PB3_PSORB1;
+               out_be32(&io->iop_psorb, tempval);
+
+               tempval = in_be32(&io->iop_pparb);
+               tempval |= (PB3_DIRB0 | PB3_DIRB1);
+               out_be32(&io->iop_pparb, tempval);
+
+               tempval = in_be32(&io->iop_pdirc);
+               tempval |= PC3_DIRC1;
+               out_be32(&io->iop_pdirc, tempval);
+
+               tempval = in_be32(&io->iop_pparc);
+               tempval |= PC3_DIRC1;
+               out_be32(&io->iop_pparc, tempval);
+
+               target = CPM_CLK_FCC3;
+               break;
+       default:
+               printk(KERN_ERR "init_fcc_ioports: invalid FCC number\n");
+               return;
+       }
+
+       /* Port C has clocks......  */
+       tempval = in_be32(&io->iop_psorc);
+       tempval &= ~(PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8));
+       out_be32(&io->iop_psorc, tempval);
+
+       tempval = in_be32(&io->iop_pdirc);
+       tempval &= ~(PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8));
+       out_be32(&io->iop_pdirc, tempval);
+       tempval = in_be32(&io->iop_pparc);
+       tempval |= (PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8));
+       out_be32(&io->iop_pparc, tempval);
+
+       cpm2_unmap(io);
+
+       /* Configure Serial Interface clock routing.
+        * First,  clear FCC bits to zero,
+        * then set the ones we want.
+        */
+       cpm2_clk_setup(target, fpi->clk_rx, CPM_CLK_RX);
+       cpm2_clk_setup(target, fpi->clk_tx, CPM_CLK_TX);
+}
+#endif
+
 static void __init mpc85xx_ads_setup_arch(void)
 {
        struct device_node *cpu;
@@ -131,6 +247,10 @@ static void __init mpc85xx_ads_setup_arch(void)
                of_node_put(cpu);
        }
 
+#ifdef CONFIG_CPM2
+       cpm2_reset();
+#endif
+
 #ifdef CONFIG_PCI
        for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
                add_bridge(np);
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.h b/arch/powerpc/platforms/85xx/mpc85xx_ads.h
new file mode 100644 (file)
index 0000000..effcbf7
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * MPC85xx ADS board definitions
+ *
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
+ *
+ * Copyright 2004 Freescale Semiconductor Inc.
+ *
+ * 2006 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.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.
+ *
+ */
+
+#ifndef __MACH_MPC85XXADS_H
+#define __MACH_MPC85XXADS_H
+
+#include <linux/config.h>
+#include <linux/initrd.h>
+#include <sysdev/fsl_soc.h>
+
+#define BCSR_ADDR              ((uint)0xf8000000)
+#define BCSR_SIZE              ((uint)(32 * 1024))
+
+#ifdef CONFIG_CPM2
+
+#define MPC85xx_CPM_OFFSET     (0x80000)
+
+#define CPM_MAP_ADDR           (get_immrbase() + MPC85xx_CPM_OFFSET)
+#define CPM_IRQ_OFFSET         60
+
+#define SIU_INT_SMC1           ((uint)0x04+CPM_IRQ_OFFSET)
+#define SIU_INT_SMC2           ((uint)0x05+CPM_IRQ_OFFSET)
+#define SIU_INT_SCC1           ((uint)0x28+CPM_IRQ_OFFSET)
+#define SIU_INT_SCC2           ((uint)0x29+CPM_IRQ_OFFSET)
+#define SIU_INT_SCC3           ((uint)0x2a+CPM_IRQ_OFFSET)
+#define SIU_INT_SCC4           ((uint)0x2b+CPM_IRQ_OFFSET)
+
+/* FCC1 Clock Source Configuration.  These can be
+ * redefined in the board specific file.
+ *    Can only choose from CLK9-12 */
+#define F1_RXCLK       12
+#define F1_TXCLK       11
+
+/* FCC2 Clock Source Configuration.  These can be
+ * redefined in the board specific file.
+ *    Can only choose from CLK13-16 */
+#define F2_RXCLK       13
+#define F2_TXCLK       14
+
+/* FCC3 Clock Source Configuration.  These can be
+ * redefined in the board specific file.
+ *    Can only choose from CLK13-16 */
+#define F3_RXCLK       15
+#define F3_TXCLK       16
+
+#endif /* CONFIG_CPM2 */
+#endif /* __MACH_MPC85XXADS_H */
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 6b57a47c5d37f3cf8ee1265c09bf1c2392d0848e..6cc59e0b458221575d6af8fbcf10b2da71cf8c6d 100644 (file)
  * 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:
+ * - Fix various assumptions related to HW CPU numbers vs. linux CPU numbers
+ *   vs node numbers in the setup code
+ * - Implement proper handling of maxcpus=1/2 (that is, routing of irqs from
+ *   a non-active node to the active node)
  */
 
 #include <linux/interrupt.h>
@@ -44,24 +50,25 @@ struct iic {
        u8 target_id;
        u8 eoi_stack[16];
        int eoi_ptr;
-       struct irq_host *host;
+       struct device_node *node;
 };
 
 static DEFINE_PER_CPU(struct iic, iic);
 #define IIC_NODE_COUNT 2
-static struct irq_host *iic_hosts[IIC_NODE_COUNT];
+static struct irq_host *iic_host;
 
 /* Convert between "pending" bits and hw irq number */
 static irq_hw_number_t iic_pending_to_hwnum(struct cbe_iic_pending_bits bits)
 {
        unsigned char unit = bits.source & 0xf;
+       unsigned char node = bits.source >> 4;
+       unsigned char class = bits.class & 3;
 
+       /* Decode IPIs */
        if (bits.flags & CBE_IIC_IRQ_IPI)
-               return IIC_IRQ_IPI0 | (bits.prio >> 4);
-       else if (bits.class <= 3)
-               return (bits.class << 4) | unit;
+               return IIC_IRQ_TYPE_IPI | (bits.prio >> 4);
        else
-               return IIC_IRQ_INVALID;
+               return (node << IIC_IRQ_NODE_SHIFT) | (class << 4) | unit;
 }
 
 static void iic_mask(unsigned int irq)
@@ -86,21 +93,70 @@ static struct irq_chip iic_chip = {
        .eoi = iic_eoi,
 };
 
+
+static void iic_ioexc_eoi(unsigned int irq)
+{
+}
+
+static void iic_ioexc_cascade(unsigned int irq, struct irq_desc *desc,
+                           struct pt_regs *regs)
+{
+       struct cbe_iic_regs *node_iic = desc->handler_data;
+       unsigned int base = (irq & 0xffffff00) | IIC_IRQ_TYPE_IOEXC;
+       unsigned long bits, ack;
+       int cascade;
+
+       for (;;) {
+               bits = in_be64(&node_iic->iic_is);
+               if (bits == 0)
+                       break;
+               /* pre-ack edge interrupts */
+               ack = bits & IIC_ISR_EDGE_MASK;
+               if (ack)
+                       out_be64(&node_iic->iic_is, ack);
+               /* handle them */
+               for (cascade = 63; cascade >= 0; cascade--)
+                       if (bits & (0x8000000000000000UL >> cascade)) {
+                               unsigned int cirq =
+                                       irq_linear_revmap(iic_host,
+                                                         base | cascade);
+                               if (cirq != NO_IRQ)
+                                       generic_handle_irq(cirq, regs);
+                       }
+               /* post-ack level interrupts */
+               ack = bits & ~IIC_ISR_EDGE_MASK;
+               if (ack)
+                       out_be64(&node_iic->iic_is, ack);
+       }
+       desc->chip->eoi(irq);
+}
+
+
+static struct irq_chip iic_ioexc_chip = {
+       .typename = " CELL-IOEX",
+       .mask = iic_mask,
+       .unmask = iic_unmask,
+       .eoi = iic_ioexc_eoi,
+};
+
 /* Get an IRQ number from the pending state register of the IIC */
 static unsigned int iic_get_irq(struct pt_regs *regs)
 {
        struct cbe_iic_pending_bits pending;
        struct iic *iic;
+       unsigned int virq;
 
        iic = &__get_cpu_var(iic);
        *(unsigned long *) &pending =
                in_be64((unsigned long __iomem *) &iic->regs->pending_destr);
+       if (!(pending.flags & CBE_IIC_IRQ_VALID))
+               return NO_IRQ;
+       virq = irq_linear_revmap(iic_host, iic_pending_to_hwnum(pending));
+       if (virq == NO_IRQ)
+               return NO_IRQ;
        iic->eoi_stack[++iic->eoi_ptr] = pending.prio;
        BUG_ON(iic->eoi_ptr > 15);
-       if (pending.flags & CBE_IIC_IRQ_VALID)
-               return irq_linear_revmap(iic->host,
-                                        iic_pending_to_hwnum(pending));
-       return NO_IRQ;
+       return virq;
 }
 
 #ifdef CONFIG_SMP
@@ -108,12 +164,7 @@ static unsigned int iic_get_irq(struct pt_regs *regs)
 /* Use the highest interrupt priorities for IPI */
 static inline int iic_ipi_to_irq(int ipi)
 {
-       return IIC_IRQ_IPI0 + IIC_NUM_IPIS - 1 - ipi;
-}
-
-static inline int iic_irq_to_ipi(int irq)
-{
-       return IIC_NUM_IPIS - 1 - (irq - IIC_IRQ_IPI0);
+       return IIC_IRQ_TYPE_IPI + 0xf - ipi;
 }
 
 void iic_setup_cpu(void)
@@ -123,7 +174,7 @@ void iic_setup_cpu(void)
 
 void iic_cause_IPI(int cpu, int mesg)
 {
-       out_be64(&per_cpu(iic, cpu).regs->generate, (IIC_NUM_IPIS - 1 - mesg) << 4);
+       out_be64(&per_cpu(iic, cpu).regs->generate, (0xf - mesg) << 4);
 }
 
 u8 iic_get_target_id(int cpu)
@@ -134,9 +185,7 @@ EXPORT_SYMBOL_GPL(iic_get_target_id);
 
 struct irq_host *iic_get_irq_host(int node)
 {
-       if (node < 0 || node >= IIC_NODE_COUNT)
-               return NULL;
-       return iic_hosts[node];
+       return iic_host;
 }
 EXPORT_SYMBOL_GPL(iic_get_irq_host);
 
@@ -149,34 +198,20 @@ static irqreturn_t iic_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
 
        return IRQ_HANDLED;
 }
-
 static void iic_request_ipi(int ipi, const char *name)
 {
-       int node, virq;
+       int virq;
 
-       for (node = 0; node < IIC_NODE_COUNT; node++) {
-               char *rname;
-               if (iic_hosts[node] == NULL)
-                       continue;
-               virq = irq_create_mapping(iic_hosts[node],
-                                         iic_ipi_to_irq(ipi));
-               if (virq == NO_IRQ) {
-                       printk(KERN_ERR
-                              "iic: failed to map IPI %s on node %d\n",
-                              name, node);
-                       continue;
-               }
-               rname = kzalloc(strlen(name) + 16, GFP_KERNEL);
-               if (rname)
-                       sprintf(rname, "%s node %d", name, node);
-               else
-                       rname = (char *)name;
-               if (request_irq(virq, iic_ipi_action, IRQF_DISABLED,
-                               rname, (void *)(long)ipi))
-                       printk(KERN_ERR
-                              "iic: failed to request IPI %s on node %d\n",
-                              name, node);
+       virq = irq_create_mapping(iic_host, iic_ipi_to_irq(ipi));
+       if (virq == NO_IRQ) {
+               printk(KERN_ERR
+                      "iic: failed to map IPI %s\n", name);
+               return;
        }
+       if (request_irq(virq, iic_ipi_action, IRQF_DISABLED, name,
+                       (void *)(long)ipi))
+               printk(KERN_ERR
+                      "iic: failed to request IPI %s\n", name);
 }
 
 void iic_request_IPIs(void)
@@ -193,16 +228,24 @@ void iic_request_IPIs(void)
 
 static int iic_host_match(struct irq_host *h, struct device_node *node)
 {
-       return h->host_data != NULL && node == h->host_data;
+       return device_is_compatible(node,
+                                   "IBM,CBEA-Internal-Interrupt-Controller");
 }
 
 static int iic_host_map(struct irq_host *h, unsigned int virq,
                        irq_hw_number_t hw)
 {
-       if (hw < IIC_IRQ_IPI0)
-               set_irq_chip_and_handler(virq, &iic_chip, handle_fasteoi_irq);
-       else
+       switch (hw & IIC_IRQ_TYPE_MASK) {
+       case IIC_IRQ_TYPE_IPI:
                set_irq_chip_and_handler(virq, &iic_chip, handle_percpu_irq);
+               break;
+       case IIC_IRQ_TYPE_IOEXC:
+               set_irq_chip_and_handler(virq, &iic_ioexc_chip,
+                                        handle_fasteoi_irq);
+               break;
+       default:
+               set_irq_chip_and_handler(virq, &iic_chip, handle_fasteoi_irq);
+       }
        return 0;
 }
 
@@ -211,11 +254,39 @@ static int iic_host_xlate(struct irq_host *h, struct device_node *ct,
                           irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 
 {
-       /* Currently, we don't translate anything. That needs to be fixed as
-        * we get better defined device-trees. iic interrupts have to be
-        * explicitely mapped by whoever needs them
-        */
-       return -ENODEV;
+       unsigned int node, ext, unit, class;
+       const u32 *val;
+
+       if (!device_is_compatible(ct,
+                                    "IBM,CBEA-Internal-Interrupt-Controller"))
+               return -ENODEV;
+       if (intsize != 1)
+               return -ENODEV;
+       val = get_property(ct, "#interrupt-cells", NULL);
+       if (val == NULL || *val != 1)
+               return -ENODEV;
+
+       node = intspec[0] >> 24;
+       ext = (intspec[0] >> 16) & 0xff;
+       class = (intspec[0] >> 8) & 0xff;
+       unit = intspec[0] & 0xff;
+
+       /* Check if node is in supported range */
+       if (node > 1)
+               return -EINVAL;
+
+       /* Build up interrupt number, special case for IO exceptions */
+       *out_hwirq = (node << IIC_IRQ_NODE_SHIFT);
+       if (unit == IIC_UNIT_IIC && class == 1)
+               *out_hwirq |= IIC_IRQ_TYPE_IOEXC | ext;
+       else
+               *out_hwirq |= IIC_IRQ_TYPE_NORMAL |
+                       (class << IIC_IRQ_CLASS_SHIFT) | unit;
+
+       /* Dummy flags, ignored by iic code */
+       *out_flags = IRQ_TYPE_EDGE_RISING;
+
+       return 0;
 }
 
 static struct irq_host_ops iic_host_ops = {
@@ -225,7 +296,7 @@ static struct irq_host_ops iic_host_ops = {
 };
 
 static void __init init_one_iic(unsigned int hw_cpu, unsigned long addr,
-                               struct irq_host *host)
+                               struct device_node *node)
 {
        /* XXX FIXME: should locate the linux CPU number from the HW cpu
         * number properly. We are lucky for now
@@ -237,19 +308,19 @@ static void __init init_one_iic(unsigned int hw_cpu, unsigned long addr,
 
        iic->target_id = ((hw_cpu & 2) << 3) | ((hw_cpu & 1) ? 0xf : 0xe);
        iic->eoi_stack[0] = 0xff;
-       iic->host = host;
+       iic->node = of_node_get(node);
        out_be64(&iic->regs->prio, 0);
 
-       printk(KERN_INFO "IIC for CPU %d at %lx mapped to %p, target id 0x%x\n",
-              hw_cpu, addr, iic->regs, iic->target_id);
+       printk(KERN_INFO "IIC for CPU %d target id 0x%x : %s\n",
+              hw_cpu, iic->target_id, node->full_name);
 }
 
 static int __init setup_iic(void)
 {
        struct device_node *dn;
        struct resource r0, r1;
-       struct irq_host *host;
-       int found = 0;
+       unsigned int node, cascade, found = 0;
+       struct cbe_iic_regs *node_iic;
        const u32 *np;
 
        for (dn = NULL;
@@ -269,19 +340,33 @@ static int __init setup_iic(void)
                        of_node_put(dn);
                        return -ENODEV;
                }
-               host = NULL;
-               if (found < IIC_NODE_COUNT) {
-                       host = irq_alloc_host(IRQ_HOST_MAP_LINEAR,
-                                             IIC_SOURCE_COUNT,
-                                             &iic_host_ops,
-                                             IIC_IRQ_INVALID);
-                       iic_hosts[found] = host;
-                       BUG_ON(iic_hosts[found] == NULL);
-                       iic_hosts[found]->host_data = of_node_get(dn);
-                       found++;
-               }
-               init_one_iic(np[0], r0.start, host);
-               init_one_iic(np[1], r1.start, host);
+               found++;
+               init_one_iic(np[0], r0.start, dn);
+               init_one_iic(np[1], r1.start, dn);
+
+               /* Setup cascade for IO exceptions. XXX cleanup tricks to get
+                * node vs CPU etc...
+                * Note that we configure the IIC_IRR here with a hard coded
+                * priority of 1. We might want to improve that later.
+                */
+               node = np[0] >> 1;
+               node_iic = cbe_get_cpu_iic_regs(np[0]);
+               cascade = node << IIC_IRQ_NODE_SHIFT;
+               cascade |= 1 << IIC_IRQ_CLASS_SHIFT;
+               cascade |= IIC_UNIT_IIC;
+               cascade = irq_create_mapping(iic_host, cascade);
+               if (cascade == NO_IRQ)
+                       continue;
+               set_irq_data(cascade, node_iic);
+               set_irq_chained_handler(cascade , iic_ioexc_cascade);
+               out_be64(&node_iic->iic_ir,
+                        (1 << 12)              /* priority */ |
+                        (node << 4)            /* dest node */ |
+                        IIC_UNIT_THREAD_0      /* route them to thread 0 */);
+               /* Flush pending (make sure it triggers if there is
+                * anything pending
+                */
+               out_be64(&node_iic->iic_is, 0xfffffffffffffffful);
        }
 
        if (found)
@@ -292,6 +377,12 @@ static int __init setup_iic(void)
 
 void __init iic_init_IRQ(void)
 {
+       /* Setup an irq host data structure */
+       iic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, IIC_SOURCE_COUNT,
+                                 &iic_host_ops, IIC_IRQ_INVALID);
+       BUG_ON(iic_host == NULL);
+       irq_set_default_host(iic_host);
+
        /* Discover and initialize iics */
        if (setup_iic() < 0)
                panic("IIC: Failed to initialize !\n");
index 5560a92ec3abf2779cfe7265317fa72f5939c915..9ba1d3c17b4b4c066dbb7cf1c7d168b01fea3f4d 100644 (file)
@@ -2,48 +2,76 @@
 #define ASM_CELL_PIC_H
 #ifdef __KERNEL__
 /*
- * Mapping of IIC pending bits into per-node
- * interrupt numbers.
+ * Mapping of IIC pending bits into per-node interrupt numbers.
  *
- * IRQ     FF CC SS PP   FF CC SS PP   Description
+ * Interrupt numbers are in the range 0...0x1ff where the top bit
+ * (0x100) represent the source node. Only 2 nodes are supported with
+ * the current code though it's trivial to extend that if necessary using
+ * higher level bits
  *
- * 00-3f   80 02 +0 00 - 80 02 +0 3f   South Bridge
- * 00-3f   80 02 +b 00 - 80 02 +b 3f   South Bridge
- * 41-4a   80 00 +1 ** - 80 00 +a **   SPU Class 0
- * 51-5a   80 01 +1 ** - 80 01 +a **   SPU Class 1
- * 61-6a   80 02 +1 ** - 80 02 +a **   SPU Class 2
- * 70-7f   C0 ** ** 00 - C0 ** ** 0f   IPI
+ * The bottom 8 bits are split into 2 type bits and 6 data bits that
+ * depend on the type:
  *
- *    F flags
- *    C class
- *    S source
- *    P Priority
- *    + node number
- *    * don't care
+ * 00 (0x00 | data) : normal interrupt. data is (class << 4) | source
+ * 01 (0x40 | data) : IO exception. data is the exception number as
+ *                    defined by bit numbers in IIC_SR
+ * 10 (0x80 | data) : IPI. data is the IPI number (obtained from the priority)
+ *                    and node is always 0 (IPIs are per-cpu, their source is
+ *                    not relevant)
+ * 11 (0xc0 | data) : reserved
  *
- * A node consists of a Cell Broadband Engine and an optional
- * south bridge device providing a maximum of 64 IRQs.
- * The south bridge may be connected to either IOIF0
- * or IOIF1.
- * Each SPE is represented as three IRQ lines, one per
- * interrupt class.
- * 16 IRQ numbers are reserved for inter processor
- * interruptions, although these are only used in the
- * range of the first node.
+ * In addition, interrupt number 0x80000000 is defined as always invalid
+ * (that is the node field is expected to never extend to move than 23 bits)
  *
- * This scheme needs 128 IRQ numbers per BIF node ID,
- * which means that with the total of 512 lines
- * available, we can have a maximum of four nodes.
  */
 
 enum {
-       IIC_IRQ_INVALID         = 0xff,
-       IIC_IRQ_MAX             = 0x3f,
-       IIC_IRQ_EXT_IOIF0       = 0x20,
-       IIC_IRQ_EXT_IOIF1       = 0x2b,
-       IIC_IRQ_IPI0            = 0x40,
-       IIC_NUM_IPIS            = 0x10, /* IRQs reserved for IPI */
-       IIC_SOURCE_COUNT        = 0x50,
+       IIC_IRQ_INVALID         = 0x80000000u,
+       IIC_IRQ_NODE_MASK       = 0x100,
+       IIC_IRQ_NODE_SHIFT      = 8,
+       IIC_IRQ_MAX             = 0x1ff,
+       IIC_IRQ_TYPE_MASK       = 0xc0,
+       IIC_IRQ_TYPE_NORMAL     = 0x00,
+       IIC_IRQ_TYPE_IOEXC      = 0x40,
+       IIC_IRQ_TYPE_IPI        = 0x80,
+       IIC_IRQ_CLASS_SHIFT     = 4,
+       IIC_IRQ_CLASS_0         = 0x00,
+       IIC_IRQ_CLASS_1         = 0x10,
+       IIC_IRQ_CLASS_2         = 0x20,
+       IIC_SOURCE_COUNT        = 0x200,
+
+       /* Here are defined the various source/dest units. Avoid using those
+        * definitions if you can, they are mostly here for reference
+        */
+       IIC_UNIT_SPU_0          = 0x4,
+       IIC_UNIT_SPU_1          = 0x7,
+       IIC_UNIT_SPU_2          = 0x3,
+       IIC_UNIT_SPU_3          = 0x8,
+       IIC_UNIT_SPU_4          = 0x2,
+       IIC_UNIT_SPU_5          = 0x9,
+       IIC_UNIT_SPU_6          = 0x1,
+       IIC_UNIT_SPU_7          = 0xa,
+       IIC_UNIT_IOC_0          = 0x0,
+       IIC_UNIT_IOC_1          = 0xb,
+       IIC_UNIT_THREAD_0       = 0xe, /* target only */
+       IIC_UNIT_THREAD_1       = 0xf, /* target only */
+       IIC_UNIT_IIC            = 0xe, /* source only (IO exceptions) */
+
+       /* Base numbers for the external interrupts */
+       IIC_IRQ_EXT_IOIF0       =
+               IIC_IRQ_TYPE_NORMAL | IIC_IRQ_CLASS_2 | IIC_UNIT_IOC_0,
+       IIC_IRQ_EXT_IOIF1       =
+               IIC_IRQ_TYPE_NORMAL | IIC_IRQ_CLASS_2 | IIC_UNIT_IOC_1,
+
+       /* Base numbers for the IIC_ISR interrupts */
+       IIC_IRQ_IOEX_TMI        = IIC_IRQ_TYPE_IOEXC | IIC_IRQ_CLASS_1 | 63,
+       IIC_IRQ_IOEX_PMI        = IIC_IRQ_TYPE_IOEXC | IIC_IRQ_CLASS_1 | 62,
+       IIC_IRQ_IOEX_ATI        = IIC_IRQ_TYPE_IOEXC | IIC_IRQ_CLASS_1 | 61,
+       IIC_IRQ_IOEX_MATBFI     = IIC_IRQ_TYPE_IOEXC | IIC_IRQ_CLASS_1 | 60,
+       IIC_IRQ_IOEX_ELDI       = IIC_IRQ_TYPE_IOEXC | IIC_IRQ_CLASS_1 | 59,
+
+       /* Which bits in IIC_ISR are edge sensitive */
+       IIC_ISR_EDGE_MASK       = 0x4ul,
 };
 
 extern void iic_init_IRQ(void);
@@ -52,7 +80,6 @@ extern void iic_request_IPIs(void);
 extern void iic_setup_cpu(void);
 
 extern u8 iic_get_target_id(int cpu);
-extern struct irq_host *iic_get_irq_host(int node);
 
 extern void spider_init_IRQ(void);
 
index 742a03282b4404f6b8d5a038c33c5478f7b06b64..608b1ebc56b28e142a170e22eabe0c8c22a41f14 100644 (file)
@@ -243,7 +243,6 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
        const u32 *imap, *tmp;
        int imaplen, intsize, unit;
        struct device_node *iic;
-       struct irq_host *iic_host;
 
 #if 0 /* Enable that when we have a way to retreive the node as well */
        /* First, we check wether we have a real "interrupts" in the device
@@ -289,11 +288,11 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
         * the iic host from the iic OF node, but that way I'm still compatible
         * with really really old old firmwares for which we don't have a node
         */
-       iic_host = iic_get_irq_host(pic->node_id);
-       if (iic_host == NULL)
-               return NO_IRQ;
        /* Manufacture an IIC interrupt number of class 2 */
-       virq = irq_create_mapping(iic_host, 0x20 | unit);
+       virq = irq_create_mapping(NULL,
+                                 (pic->node_id << IIC_IRQ_NODE_SHIFT) |
+                                 (2 << IIC_IRQ_CLASS_SHIFT) |
+                                 unit);
        if (virq == NO_IRQ)
                printk(KERN_ERR "spider_pic: failed to map cascade !");
        return virq;
index 3bd36d46ab4ae4f6b24dbe14c0dd1c18b2b57cdd..f78680346e5fe0dc72fbe4ba70dd2c4152332da1 100644 (file)
@@ -538,7 +538,7 @@ static void __iomem * __init map_spe_prop(struct spu *spu,
 
        const void *p;
        int proplen;
-       voidret = NULL;
+       void __iomem *ret = NULL;
        int err = 0;
 
        p = get_property(n, name, &proplen);
@@ -562,30 +562,29 @@ static void spu_unmap(struct spu *spu)
        iounmap(spu->priv2);
        iounmap(spu->priv1);
        iounmap(spu->problem);
-       iounmap((u8 __iomem *)spu->local_store);
+       iounmap((__force u8 __iomem *)spu->local_store);
 }
 
 /* This function shall be abstracted for HV platforms */
 static int __init spu_map_interrupts(struct spu *spu, struct device_node *np)
 {
-       struct irq_host *host;
        unsigned int isrc;
        const u32 *tmp;
 
-       host = iic_get_irq_host(spu->node);
-       if (host == NULL)
-               return -ENODEV;
-
-       /* Get the interrupt source from the device-tree */
+       /* Get the interrupt source unit from the device-tree */
        tmp = get_property(np, "isrc", NULL);
        if (!tmp)
                return -ENODEV;
-       spu->isrc = isrc = tmp[0];
+       isrc = tmp[0];
+
+       /* Add the node number */
+       isrc |= spu->node << IIC_IRQ_NODE_SHIFT;
+       spu->isrc = isrc;
 
        /* Now map interrupts of all 3 classes */
-       spu->irqs[0] = irq_create_mapping(host, 0x00 | isrc);
-       spu->irqs[1] = irq_create_mapping(host, 0x10 | isrc);
-       spu->irqs[2] = irq_create_mapping(host, 0x20 | isrc);
+       spu->irqs[0] = irq_create_mapping(NULL, IIC_IRQ_CLASS_0 | isrc);
+       spu->irqs[1] = irq_create_mapping(NULL, IIC_IRQ_CLASS_1 | isrc);
+       spu->irqs[2] = irq_create_mapping(NULL, IIC_IRQ_CLASS_2 | isrc);
 
        /* Right now, we only fail if class 2 failed */
        return spu->irqs[2] == NO_IRQ ? -EINVAL : 0;
index 58e794f9da1b6a5b920f95ba6fe57f0f054d1cb7..51fd197ab5dd1f98ac9f1bfbab25ef7b6f839ad4 100644 (file)
@@ -1342,7 +1342,7 @@ static u64 spufs_id_get(void *data)
 
        return num;
 }
-DEFINE_SIMPLE_ATTRIBUTE(spufs_id_ops, spufs_id_get, 0, "0x%llx\n")
+DEFINE_SIMPLE_ATTRIBUTE(spufs_id_ops, spufs_id_get, NULL, "0x%llx\n")
 
 struct tree_descr spufs_dir_contents[] = {
        { "mem",  &spufs_mem_fops,  0666, },
index c8670f519734aab795e40d4fc8b10e247b9dccbb..efc452e71ab0f03b93b4d3178d28cc05ef1200c1 100644 (file)
@@ -234,7 +234,7 @@ static void spu_hw_runcntl_stop(struct spu_context *ctx)
 
 static int spu_hw_set_mfc_query(struct spu_context * ctx, u32 mask, u32 mode)
 {
-       struct spu_problem *prob = ctx->spu->problem;
+       struct spu_problem __iomem *prob = ctx->spu->problem;
        int ret;
 
        spin_lock_irq(&ctx->spu->register_lock);
@@ -263,7 +263,7 @@ static int spu_hw_send_mfc_command(struct spu_context *ctx,
                                        struct mfc_dma_command *cmd)
 {
        u32 status;
-       struct spu_problem *prob = ctx->spu->problem;
+       struct spu_problem __iomem *prob = ctx->spu->problem;
 
        spin_lock_irq(&ctx->spu->register_lock);
        out_be32(&prob->mfc_lsa_W, cmd->lsa);
index 1a2c2a50f9221c912e3c5a465f97a495d03fac9c..1983b640bac117593c84cd42e197fbb9c9771ce3 100644 (file)
@@ -357,7 +357,7 @@ static int dma_and_signal_ce_msg(char *ce_msg,
  */
 static int shutdown(void)
 {
-       int rc = kill_proc(1, SIGINT, 1);
+       int rc = kill_cad_pid(SIGINT, 1);
 
        if (rc) {
                printk(KERN_ALERT "mf.c: SIGINT to init failed (%d), "
index 3eb12065df23ec635aaaafb2dac1a8d4b5e003ef..4aa165e010d91966214dc01774ef5037f6044b2d 100644 (file)
@@ -262,14 +262,6 @@ void __init iSeries_pci_final_fixup(void)
        mf_display_src(0xC9000200);
 }
 
-void pcibios_fixup_bus(struct pci_bus *PciBus)
-{
-}
-
-void pcibios_fixup_resources(struct pci_dev *pdev)
-{
-}
-
 /*
  * Look down the chain to find the matching Device Device
  */
index 7f1953066ff8f7ae2f26d35a1511feeac24b1012..a0ff7ba7d666addc2a78a3f20276e9de56d09f61 100644 (file)
@@ -649,15 +649,21 @@ static void iseries_dedicated_idle(void)
 void __init iSeries_init_IRQ(void) { }
 #endif
 
+/*
+ * iSeries has no legacy IO, anything calling this function has to
+ * fail or bad things will happen
+ */
+static int iseries_check_legacy_ioport(unsigned int baseport)
+{
+       return -ENODEV;
+}
+
 static int __init iseries_probe(void)
 {
        unsigned long root = of_get_flat_dt_root();
        if (!of_flat_dt_is_compatible(root, "IBM,iSeries"))
                return 0;
 
-       powerpc_firmware_features |= FW_FEATURE_ISERIES;
-       powerpc_firmware_features |= FW_FEATURE_LPAR;
-
        hpte_init_iSeries();
 
        return 1;
@@ -680,6 +686,7 @@ define_machine(iseries) {
        .calibrate_decr = generic_calibrate_decr,
        .progress       = iSeries_progress,
        .probe          = iseries_probe,
+       .check_legacy_ioport    = iseries_check_legacy_ioport,
        /* XXX Implement enable_pmcs for iSeries */
 };
 
@@ -687,6 +694,9 @@ void * __init iSeries_early_setup(void)
 {
        unsigned long phys_mem_size;
 
+       powerpc_firmware_features |= FW_FEATURE_ISERIES;
+       powerpc_firmware_features |= FW_FEATURE_LPAR;
+
        iSeries_fixup_klimit();
 
        /*
index c3aa46b8e2b9db064351ab75585d01b63f1913d0..1b827618e05f9f59f412896df8b0f61f5be06191 100644 (file)
@@ -96,14 +96,14 @@ static unsigned long u3_agp_cfa1(u8 bus, u8 devfn, u8 off)
                1UL;
 }
 
-static unsigned long u3_agp_cfg_access(struct pci_controller* hose,
+static volatile void __iomem *u3_agp_cfg_access(struct pci_controller* hose,
                                       u8 bus, u8 dev_fn, u8 offset)
 {
        unsigned int caddr;
 
        if (bus == hose->first_busno) {
                if (dev_fn < (11 << 3))
-                       return 0;
+                       return NULL;
                caddr = u3_agp_cfa0(dev_fn, offset);
        } else
                caddr = u3_agp_cfa1(bus, dev_fn, offset);
@@ -114,14 +114,14 @@ static unsigned long u3_agp_cfg_access(struct pci_controller* hose,
        } while (in_le32(hose->cfg_addr) != caddr);
 
        offset &= 0x07;
-       return ((unsigned long)hose->cfg_data) + offset;
+       return hose->cfg_data + offset;
 }
 
 static int u3_agp_read_config(struct pci_bus *bus, unsigned int devfn,
                              int offset, int len, u32 *val)
 {
        struct pci_controller *hose;
-       unsigned long addr;
+       volatile void __iomem *addr;
 
        hose = pci_bus_to_host(bus);
        if (hose == NULL)
@@ -136,13 +136,13 @@ static int u3_agp_read_config(struct pci_bus *bus, unsigned int devfn,
         */
        switch (len) {
        case 1:
-               *val = in_8((u8 *)addr);
+               *val = in_8(addr);
                break;
        case 2:
-               *val = in_le16((u16 *)addr);
+               *val = in_le16(addr);
                break;
        default:
-               *val = in_le32((u32 *)addr);
+               *val = in_le32(addr);
                break;
        }
        return PCIBIOS_SUCCESSFUL;
@@ -152,7 +152,7 @@ static int u3_agp_write_config(struct pci_bus *bus, unsigned int devfn,
                               int offset, int len, u32 val)
 {
        struct pci_controller *hose;
-       unsigned long addr;
+       volatile void __iomem *addr;
 
        hose = pci_bus_to_host(bus);
        if (hose == NULL)
@@ -167,16 +167,16 @@ static int u3_agp_write_config(struct pci_bus *bus, unsigned int devfn,
         */
        switch (len) {
        case 1:
-               out_8((u8 *)addr, val);
-               (void) in_8((u8 *)addr);
+               out_8(addr, val);
+               (void) in_8(addr);
                break;
        case 2:
-               out_le16((u16 *)addr, val);
-               (void) in_le16((u16 *)addr);
+               out_le16(addr, val);
+               (void) in_le16(addr);
                break;
        default:
-               out_le32((u32 *)addr, val);
-               (void) in_le32((u32 *)addr);
+               out_le32(addr, val);
+               (void) in_le32(addr);
                break;
        }
        return PCIBIOS_SUCCESSFUL;
@@ -198,22 +198,22 @@ static unsigned long u3_ht_cfa1(u8 bus, u8 devfn, u8 off)
        return u3_ht_cfa0(devfn, off) + (bus << 16) + 0x01000000UL;
 }
 
-static unsigned long u3_ht_cfg_access(struct pci_controller* hose,
+static volatile void __iomem *u3_ht_cfg_access(struct pci_controller* hose,
                                      u8 bus, u8 devfn, u8 offset)
 {
        if (bus == hose->first_busno) {
                if (PCI_SLOT(devfn) == 0)
-                       return 0;
-               return ((unsigned long)hose->cfg_data) + u3_ht_cfa0(devfn, offset);
+                       return NULL;
+               return hose->cfg_data + u3_ht_cfa0(devfn, offset);
        } else
-               return ((unsigned long)hose->cfg_data) + u3_ht_cfa1(bus, devfn, offset);
+               return hose->cfg_data + u3_ht_cfa1(bus, devfn, offset);
 }
 
 static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
                             int offset, int len, u32 *val)
 {
        struct pci_controller *hose;
-       unsigned long addr;
+       volatile void __iomem *addr;
 
        hose = pci_bus_to_host(bus);
        if (hose == NULL)
@@ -232,13 +232,13 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
         */
        switch (len) {
        case 1:
-               *val = in_8((u8 *)addr);
+               *val = in_8(addr);
                break;
        case 2:
-               *val = in_le16((u16 *)addr);
+               *val = in_le16(addr);
                break;
        default:
-               *val = in_le32((u32 *)addr);
+               *val = in_le32(addr);
                break;
        }
        return PCIBIOS_SUCCESSFUL;
@@ -248,7 +248,7 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
                              int offset, int len, u32 val)
 {
        struct pci_controller *hose;
-       unsigned long addr;
+       volatile void __iomem *addr;
 
        hose = pci_bus_to_host(bus);
        if (hose == NULL)
@@ -266,16 +266,16 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
         */
        switch (len) {
        case 1:
-               out_8((u8 *)addr, val);
-               (void) in_8((u8 *)addr);
+               out_8(addr, val);
+               (void) in_8(addr);
                break;
        case 2:
-               out_le16((u16 *)addr, val);
-               (void) in_le16((u16 *)addr);
+               out_le16(addr, val);
+               (void) in_le16(addr);
                break;
        default:
-               out_le32((u32 *)addr, val);
-               (void) in_le32((u32 *)addr);
+               out_le32(addr, val);
+               (void) in_le32(addr);
                break;
        }
        return PCIBIOS_SUCCESSFUL;
@@ -315,7 +315,7 @@ static void __init setup_u3_ht(struct pci_controller* hose)
         * the reg address cell, we shall fix that by killing struct
         * reg_property and using some accessor functions instead
         */
-       hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000, 0x02000000);
+       hose->cfg_data = ioremap(0xf2000000, 0x02000000);
 
        hose->first_busno = 0;
        hose->last_busno = 0xef;
index ce1a235855f7557e0f15ed061429254d9fff41d4..379db05b0082418ee7232389e1d05b44cad4bc60 100644 (file)
@@ -111,8 +111,6 @@ void udbg_scc_init(int force_scc)
        pmac_call_feature(PMAC_FTR_SCC_ENABLE, ch,
                          PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);
 
-
-       /* Setup for 57600 8N1 */
        if (ch == ch_a)
                addr += 0x20;
        sccc = ioremap(addr & PAGE_MASK, PAGE_SIZE) ;
@@ -125,9 +123,21 @@ void udbg_scc_init(int force_scc)
                x = in_8(sccc);
        out_8(sccc, 0x09);              /* reset A or B side */
        out_8(sccc, 0xc0);
+
+       /* If SCC was the OF output port, read the BRG value, else
+        * Setup for 57600 8N1
+        */
+       if (ch_def != NULL) {
+               out_8(sccc, 13);
+               scc_inittab[1] = in_8(sccc);
+               out_8(sccc, 12);
+               scc_inittab[3] = in_8(sccc);
+       }
+
        for (i = 0; i < sizeof(scc_inittab); ++i)
                out_8(sccc, scc_inittab[i]);
 
+
        udbg_putc = udbg_scc_putc;
        udbg_getc = udbg_scc_getc;
        udbg_getc_poll = udbg_scc_getc_poll;
index 84bc8f7e17ef77481269204890e2b576e1c2810f..3c2d63ebf787fae9e60e3c98713c36d3e1590d8f 100644 (file)
@@ -225,6 +225,7 @@ static void __eeh_mark_slot (struct device_node *dn, int mode_flag)
 
 void eeh_mark_slot (struct device_node *dn, int mode_flag)
 {
+       struct pci_dev *dev;
        dn = find_device_pe (dn);
 
        /* Back up one, since config addrs might be shared */
@@ -232,6 +233,12 @@ void eeh_mark_slot (struct device_node *dn, int mode_flag)
                dn = dn->parent;
 
        PCI_DN(dn)->eeh_mode |= mode_flag;
+
+       /* Mark the pci device too */
+       dev = PCI_DN(dn)->pcidev;
+       if (dev)
+               dev->error_state = pci_channel_io_frozen;
+
        __eeh_mark_slot (dn->child, mode_flag);
 }
 
index 8ed362140452e850bb44c2bc2b32b1a68ff8bef3..f82b13e531a3d8a06c600e646103045f57b065b3 100644 (file)
@@ -180,7 +180,7 @@ static void __init pseries_mpic_init_IRQ(void)
 
        cascade_irq = irq_of_parse_and_map(cascade, 0);
        if (cascade == NO_IRQ) {
-               printk(KERN_ERR "xics: failed to map cascade interrupt");
+               printk(KERN_ERR "mpic: failed to map cascade interrupt");
                return;
        }
 
@@ -342,7 +342,7 @@ static int __init pSeries_init_panel(void)
 {
        /* Manually leave the kernel version on the panel. */
        ppc_md.progress("Linux ppc64\n", 0);
-       ppc_md.progress(system_utsname.release, 0);
+       ppc_md.progress(init_utsname()->version, 0);
 
        return 0;
 }
@@ -415,12 +415,6 @@ static int pSeries_check_legacy_ioport(unsigned int baseport)
                        return -ENODEV;
                of_node_put(np);
                break;
-       case PARALLEL_BASE:
-               np = of_find_node_by_type(NULL, "parallel");
-               if (np == NULL)
-                       return -ENODEV;
-               of_node_put(np);
-               break;
        }
        return 0;
 }
@@ -483,7 +477,6 @@ static void pseries_dedicated_idle_sleep(void)
 { 
        unsigned int cpu = smp_processor_id();
        unsigned long start_snooze;
-       unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
 
        /*
         * Indicate to the HV that we are idle. Now would be
@@ -496,9 +489,9 @@ static void pseries_dedicated_idle_sleep(void)
         * has been checked recently.  If we should poll for a little
         * while, do so.
         */
-       if (*smt_snooze_delay) {
+       if (__get_cpu_var(smt_snooze_delay)) {
                start_snooze = get_tb() +
-                       *smt_snooze_delay * tb_ticks_per_usec;
+                       __get_cpu_var(smt_snooze_delay) * tb_ticks_per_usec;
                local_irq_enable();
                set_thread_flag(TIF_POLLING_NRFLAG);
 
@@ -518,24 +511,7 @@ static void pseries_dedicated_idle_sleep(void)
                        goto out;
        }
 
-       /*
-        * If not SMT, cede processor.  If CPU is running SMT
-        * cede if the other thread is not idle, so that it can
-        * go single-threaded.  If the other thread is idle,
-        * we ask the hypervisor if it has pending work it
-        * wants to do and cede if it does.  Otherwise we keep
-        * polling in order to reduce interrupt latency.
-        *
-        * Doing the cede when the other thread is active will
-        * result in this thread going dormant, meaning the other
-        * thread gets to run in single-threaded (ST) mode, which
-        * is slightly faster than SMT mode with this thread at
-        * very low priority.  The cede enables interrupts, which
-        * doesn't matter here.
-        */
-       if (!cpu_has_feature(CPU_FTR_SMT) || !lppaca[cpu ^ 1].idle
-           || poll_pending() == H_PENDING)
-               cede_processor();
+       cede_processor();
 
 out:
        HMT_medium();
index e5e999ea891ad43f1e3442118724d256fc35e6ce..91f052d8cce03100f10bc8bcf22eb4177d404bb2 100644 (file)
@@ -12,8 +12,14 @@ obj-$(CONFIG_MMIO_NVRAM)     += mmio_nvram.o
 obj-$(CONFIG_FSL_SOC)          += fsl_soc.o
 obj-$(CONFIG_PPC_TODC)         += todc.o
 obj-$(CONFIG_TSI108_BRIDGE)    += tsi108_pci.o tsi108_dev.o
+obj-$(CONFIG_QUICC_ENGINE)     += qe_lib/
 
 ifeq ($(CONFIG_PPC_MERGE),y)
 obj-$(CONFIG_PPC_I8259)                += i8259.o
 obj-$(CONFIG_PPC_83xx)         += ipic.o
 endif
+
+# Temporary hack until we have migrated to asm-powerpc
+ifeq ($(ARCH),powerpc)
+obj-$(CONFIG_CPM2)             += cpm2_common.o cpm2_pic.o
+endif
diff --git a/arch/powerpc/sysdev/cpm2_common.c b/arch/powerpc/sysdev/cpm2_common.c
new file mode 100644 (file)
index 0000000..ec26599
--- /dev/null
@@ -0,0 +1,309 @@
+/*
+ * General Purpose functions for the global management of the
+ * 8260 Communication Processor Module.
+ * Copyright (c) 1999-2001 Dan Malek <dan@embeddedalley.com>
+ * Copyright (c) 2000 MontaVista Software, Inc (source@mvista.com)
+ *     2.3.99 Updates
+ *
+ * 2006 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *     Merged to arch/powerpc from arch/ppc/syslib/cpm2_common.c
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/*
+ *
+ * In addition to the individual control of the communication
+ * channels, there are a few functions that globally affect the
+ * communication processor.
+ *
+ * Buffer descriptors must be allocated from the dual ported memory
+ * space.  The allocator for that is here.  When the communication
+ * process is reset, we reclaim the memory available.  There is
+ * currently no deallocator for this memory.
+ */
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mpc8260.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/cpm2.h>
+#include <asm/rheap.h>
+#include <asm/fs_pd.h>
+
+#include <sysdev/fsl_soc.h>
+
+static void cpm2_dpinit(void);
+cpm_cpm2_t     *cpmp;          /* Pointer to comm processor space */
+
+/* We allocate this here because it is used almost exclusively for
+ * the communication processor devices.
+ */
+cpm2_map_t *cpm2_immr;
+intctl_cpm2_t *cpm2_intctl;
+
+#define CPM_MAP_SIZE   (0x40000)       /* 256k - the PQ3 reserve this amount
+                                          of space for CPM as it is larger
+                                          than on PQ2 */
+
+void
+cpm2_reset(void)
+{
+       cpm2_immr = (cpm2_map_t *)ioremap(CPM_MAP_ADDR, CPM_MAP_SIZE);
+       cpm2_intctl = cpm2_map(im_intctl);
+
+       /* Reclaim the DP memory for our use.
+        */
+       cpm2_dpinit();
+
+       /* Tell everyone where the comm processor resides.
+        */
+       cpmp = &cpm2_immr->im_cpm;
+}
+
+/* Set a baud rate generator.  This needs lots of work.  There are
+ * eight BRGs, which can be connected to the CPM channels or output
+ * as clocks.  The BRGs are in two different block of internal
+ * memory mapped space.
+ * The baud rate clock is the system clock divided by something.
+ * It was set up long ago during the initial boot phase and is
+ * is given to us.
+ * Baud rate clocks are zero-based in the driver code (as that maps
+ * to port numbers).  Documentation uses 1-based numbering.
+ */
+#define BRG_INT_CLK    (get_brgfreq())
+#define BRG_UART_CLK   (BRG_INT_CLK/16)
+
+/* This function is used by UARTS, or anything else that uses a 16x
+ * oversampled clock.
+ */
+void
+cpm_setbrg(uint brg, uint rate)
+{
+       volatile uint   *bp;
+
+       /* This is good enough to get SMCs running.....
+       */
+       if (brg < 4) {
+               bp = cpm2_map_size(im_brgc1, 16);
+       } else {
+               bp = cpm2_map_size(im_brgc5, 16);
+               brg -= 4;
+       }
+       bp += brg;
+       *bp = ((BRG_UART_CLK / rate) << 1) | CPM_BRG_EN;
+
+       cpm2_unmap(bp);
+}
+
+/* This function is used to set high speed synchronous baud rate
+ * clocks.
+ */
+void
+cpm2_fastbrg(uint brg, uint rate, int div16)
+{
+       volatile uint   *bp;
+
+       if (brg < 4) {
+               bp = cpm2_map_size(im_brgc1, 16);
+       }
+       else {
+               bp = cpm2_map_size(im_brgc5, 16);
+               brg -= 4;
+       }
+       bp += brg;
+       *bp = ((BRG_INT_CLK / rate) << 1) | CPM_BRG_EN;
+       if (div16)
+               *bp |= CPM_BRG_DIV16;
+
+       cpm2_unmap(bp);
+}
+
+int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode)
+{
+       int ret = 0;
+       int shift;
+       int i, bits = 0;
+       cpmux_t *im_cpmux;
+       u32 *reg;
+       u32 mask = 7;
+       u8 clk_map [24][3] = {
+               {CPM_CLK_FCC1, CPM_BRG5, 0},
+               {CPM_CLK_FCC1, CPM_BRG6, 1},
+               {CPM_CLK_FCC1, CPM_BRG7, 2},
+               {CPM_CLK_FCC1, CPM_BRG8, 3},
+               {CPM_CLK_FCC1, CPM_CLK9, 4},
+               {CPM_CLK_FCC1, CPM_CLK10, 5},
+               {CPM_CLK_FCC1, CPM_CLK11, 6},
+               {CPM_CLK_FCC1, CPM_CLK12, 7},
+               {CPM_CLK_FCC2, CPM_BRG5, 0},
+               {CPM_CLK_FCC2, CPM_BRG6, 1},
+               {CPM_CLK_FCC2, CPM_BRG7, 2},
+               {CPM_CLK_FCC2, CPM_BRG8, 3},
+               {CPM_CLK_FCC2, CPM_CLK13, 4},
+               {CPM_CLK_FCC2, CPM_CLK14, 5},
+               {CPM_CLK_FCC2, CPM_CLK15, 6},
+               {CPM_CLK_FCC2, CPM_CLK16, 7},
+               {CPM_CLK_FCC3, CPM_BRG5, 0},
+               {CPM_CLK_FCC3, CPM_BRG6, 1},
+               {CPM_CLK_FCC3, CPM_BRG7, 2},
+               {CPM_CLK_FCC3, CPM_BRG8, 3},
+               {CPM_CLK_FCC3, CPM_CLK13, 4},
+               {CPM_CLK_FCC3, CPM_CLK14, 5},
+               {CPM_CLK_FCC3, CPM_CLK15, 6},
+               {CPM_CLK_FCC3, CPM_CLK16, 7}
+               };
+
+       im_cpmux = cpm2_map(im_cpmux);
+
+       switch (target) {
+       case CPM_CLK_SCC1:
+               reg = &im_cpmux->cmx_scr;
+               shift = 24;
+       case CPM_CLK_SCC2:
+               reg = &im_cpmux->cmx_scr;
+               shift = 16;
+               break;
+       case CPM_CLK_SCC3:
+               reg = &im_cpmux->cmx_scr;
+               shift = 8;
+               break;
+       case CPM_CLK_SCC4:
+               reg = &im_cpmux->cmx_scr;
+               shift = 0;
+               break;
+       case CPM_CLK_FCC1:
+               reg = &im_cpmux->cmx_fcr;
+               shift = 24;
+               break;
+       case CPM_CLK_FCC2:
+               reg = &im_cpmux->cmx_fcr;
+               shift = 16;
+               break;
+       case CPM_CLK_FCC3:
+               reg = &im_cpmux->cmx_fcr;
+               shift = 8;
+               break;
+       default:
+               printk(KERN_ERR "cpm2_clock_setup: invalid clock target\n");
+               return -EINVAL;
+       }
+
+       if (mode == CPM_CLK_RX)
+               shift +=3;
+
+       for (i=0; i<24; i++) {
+               if (clk_map[i][0] == target && clk_map[i][1] == clock) {
+                       bits = clk_map[i][2];
+                       break;
+               }
+       }
+       if (i == sizeof(clk_map)/3)
+           ret = -EINVAL;
+
+       bits <<= shift;
+       mask <<= shift;
+       out_be32(reg, (in_be32(reg) & ~mask) | bits);
+
+       cpm2_unmap(im_cpmux);
+       return ret;
+}
+
+/*
+ * dpalloc / dpfree bits.
+ */
+static spinlock_t cpm_dpmem_lock;
+/* 16 blocks should be enough to satisfy all requests
+ * until the memory subsystem goes up... */
+static rh_block_t cpm_boot_dpmem_rh_block[16];
+static rh_info_t cpm_dpmem_info;
+static u8* im_dprambase;
+
+static void cpm2_dpinit(void)
+{
+       spin_lock_init(&cpm_dpmem_lock);
+
+       im_dprambase = ioremap(CPM_MAP_ADDR, CPM_DATAONLY_BASE + CPM_DATAONLY_SIZE);
+
+       /* initialize the info header */
+       rh_init(&cpm_dpmem_info, 1,
+                       sizeof(cpm_boot_dpmem_rh_block) /
+                       sizeof(cpm_boot_dpmem_rh_block[0]),
+                       cpm_boot_dpmem_rh_block);
+
+       /* Attach the usable dpmem area */
+       /* XXX: This is actually crap. CPM_DATAONLY_BASE and
+        * CPM_DATAONLY_SIZE is only a subset of the available dpram. It
+        * varies with the processor and the microcode patches activated.
+        * But the following should be at least safe.
+        */
+       rh_attach_region(&cpm_dpmem_info, (void *)CPM_DATAONLY_BASE,
+                       CPM_DATAONLY_SIZE);
+}
+
+/* This function returns an index into the DPRAM area.
+ */
+uint cpm_dpalloc(uint size, uint align)
+{
+       void *start;
+       unsigned long flags;
+
+       spin_lock_irqsave(&cpm_dpmem_lock, flags);
+       cpm_dpmem_info.alignment = align;
+       start = rh_alloc(&cpm_dpmem_info, size, "commproc");
+       spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
+
+       return (uint)start;
+}
+EXPORT_SYMBOL(cpm_dpalloc);
+
+int cpm_dpfree(uint offset)
+{
+       int ret;
+       unsigned long flags;
+
+       spin_lock_irqsave(&cpm_dpmem_lock, flags);
+       ret = rh_free(&cpm_dpmem_info, (void *)offset);
+       spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(cpm_dpfree);
+
+/* not sure if this is ever needed */
+uint cpm_dpalloc_fixed(uint offset, uint size, uint align)
+{
+       void *start;
+       unsigned long flags;
+
+       spin_lock_irqsave(&cpm_dpmem_lock, flags);
+       cpm_dpmem_info.alignment = align;
+       start = rh_alloc_fixed(&cpm_dpmem_info, (void *)offset, size, "commproc");
+       spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
+
+       return (uint)start;
+}
+EXPORT_SYMBOL(cpm_dpalloc_fixed);
+
+void cpm_dpdump(void)
+{
+       rh_dump(&cpm_dpmem_info);
+}
+EXPORT_SYMBOL(cpm_dpdump);
+
+void *cpm_dpram_addr(uint offset)
+{
+       return (void *)(im_dprambase + offset);
+}
+EXPORT_SYMBOL(cpm_dpram_addr);
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
new file mode 100644 (file)
index 0000000..28b0189
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+ * Platform information definitions.
+ *
+ * Copied from arch/ppc/syslib/cpm2_pic.c with minor subsequent updates
+ * to make in work in arch/powerpc/. Original (c) belongs to Dan Malek.
+ *
+ * Author:  Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * 1999-2001 (c) Dan Malek <dan@embeddedalley.com>
+ * 2006 (c) MontaVista Software, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/* The CPM2 internal interrupt controller.  It is usually
+ * the only interrupt controller.
+ * There are two 32-bit registers (high/low) for up to 64
+ * possible interrupts.
+ *
+ * Now, the fun starts.....Interrupt Numbers DO NOT MAP
+ * in a simple arithmetic fashion to mask or pending registers.
+ * That is, interrupt 4 does not map to bit position 4.
+ * We create two tables, indexed by vector number, to indicate
+ * which register to use and which bit in the register to use.
+ */
+
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/irq.h>
+
+#include <asm/immap_cpm2.h>
+#include <asm/mpc8260.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+
+#include "cpm2_pic.h"
+
+static struct device_node *cpm2_pic_node;
+static struct irq_host *cpm2_pic_host;
+#define NR_MASK_WORDS   ((NR_IRQS + 31) / 32)
+static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
+
+static const u_char irq_to_siureg[] = {
+       1, 1, 1, 1, 1, 1, 1, 1,
+       1, 1, 1, 1, 1, 1, 1, 1,
+       0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0,
+       1, 1, 1, 1, 1, 1, 1, 1,
+       1, 1, 1, 1, 1, 1, 1, 1,
+       0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* bit numbers do not match the docs, these are precomputed so the bit for
+ * a given irq is (1 << irq_to_siubit[irq]) */
+static const u_char irq_to_siubit[] = {
+        0, 15, 14, 13, 12, 11, 10,  9,
+        8,  7,  6,  5,  4,  3,  2,  1,
+        2,  1,  0, 14, 13, 12, 11, 10,
+        9,  8,  7,  6,  5,  4,  3,  0,
+       31, 30, 29, 28, 27, 26, 25, 24,
+       23, 22, 21, 20, 19, 18, 17, 16,
+       16, 17, 18, 19, 20, 21, 22, 23,
+       24, 25, 26, 27, 28, 29, 30, 31,
+};
+
+static void cpm2_mask_irq(unsigned int irq_nr)
+{
+       int     bit, word;
+       volatile uint   *simr;
+
+       irq_nr -= CPM_IRQ_OFFSET;
+
+       bit = irq_to_siubit[irq_nr];
+       word = irq_to_siureg[irq_nr];
+
+       simr = &(cpm2_intctl->ic_simrh);
+       ppc_cached_irq_mask[word] &= ~(1 << bit);
+       simr[word] = ppc_cached_irq_mask[word];
+}
+
+static void cpm2_unmask_irq(unsigned int irq_nr)
+{
+       int     bit, word;
+       volatile uint   *simr;
+
+       irq_nr -= CPM_IRQ_OFFSET;
+
+       bit = irq_to_siubit[irq_nr];
+       word = irq_to_siureg[irq_nr];
+
+       simr = &(cpm2_intctl->ic_simrh);
+       ppc_cached_irq_mask[word] |= 1 << bit;
+       simr[word] = ppc_cached_irq_mask[word];
+}
+
+static void cpm2_mask_and_ack(unsigned int irq_nr)
+{
+       int     bit, word;
+       volatile uint   *simr, *sipnr;
+
+       irq_nr -= CPM_IRQ_OFFSET;
+
+       bit = irq_to_siubit[irq_nr];
+       word = irq_to_siureg[irq_nr];
+
+       simr = &(cpm2_intctl->ic_simrh);
+       sipnr = &(cpm2_intctl->ic_sipnrh);
+       ppc_cached_irq_mask[word] &= ~(1 << bit);
+       simr[word] = ppc_cached_irq_mask[word];
+       sipnr[word] = 1 << bit;
+}
+
+static void cpm2_end_irq(unsigned int irq_nr)
+{
+       int     bit, word;
+       volatile uint   *simr;
+
+       if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
+                       && irq_desc[irq_nr].action) {
+
+               irq_nr -= CPM_IRQ_OFFSET;
+               bit = irq_to_siubit[irq_nr];
+               word = irq_to_siureg[irq_nr];
+
+               simr = &(cpm2_intctl->ic_simrh);
+               ppc_cached_irq_mask[word] |= 1 << bit;
+               simr[word] = ppc_cached_irq_mask[word];
+               /*
+                * Work around large numbers of spurious IRQs on PowerPC 82xx
+                * systems.
+                */
+               mb();
+       }
+}
+
+static struct irq_chip cpm2_pic = {
+       .typename = " CPM2 SIU ",
+       .enable = cpm2_unmask_irq,
+       .disable = cpm2_mask_irq,
+       .unmask = cpm2_unmask_irq,
+       .mask_ack = cpm2_mask_and_ack,
+       .end = cpm2_end_irq,
+};
+
+unsigned int cpm2_get_irq(struct pt_regs *regs)
+{
+       int irq;
+       unsigned long bits;
+
+       /* For CPM2, read the SIVEC register and shift the bits down
+         * to get the irq number.         */
+        bits = cpm2_intctl->ic_sivec;
+        irq = bits >> 26;
+
+       if (irq == 0)
+               return(-1);
+       return irq+CPM_IRQ_OFFSET;
+}
+
+static int cpm2_pic_host_match(struct irq_host *h, struct device_node *node)
+{
+       return cpm2_pic_node == NULL || cpm2_pic_node == node;
+}
+
+static int cpm2_pic_host_map(struct irq_host *h, unsigned int virq,
+                         irq_hw_number_t hw)
+{
+       pr_debug("cpm2_pic_host_map(%d, 0x%lx)\n", virq, hw);
+
+       get_irq_desc(virq)->status |= IRQ_LEVEL;
+       set_irq_chip_and_handler(virq, &cpm2_pic, handle_level_irq);
+       return 0;
+}
+
+static void cpm2_host_unmap(struct irq_host *h, unsigned int virq)
+{
+       /* Make sure irq is masked in hardware */
+       cpm2_mask_irq(virq);
+
+       /* remove chip and handler */
+       set_irq_chip_and_handler(virq, NULL, NULL);
+}
+
+static int cpm2_pic_host_xlate(struct irq_host *h, struct device_node *ct,
+                           u32 *intspec, unsigned int intsize,
+                           irq_hw_number_t *out_hwirq, unsigned int *out_flags)
+{
+       static const unsigned char map_cpm2_senses[4] = {
+               IRQ_TYPE_LEVEL_LOW,
+               IRQ_TYPE_LEVEL_HIGH,
+               IRQ_TYPE_EDGE_FALLING,
+               IRQ_TYPE_EDGE_RISING,
+       };
+
+       *out_hwirq = intspec[0];
+       if (intsize > 1 && intspec[1] < 4)
+               *out_flags = map_cpm2_senses[intspec[1]];
+       else
+               *out_flags = IRQ_TYPE_NONE;
+
+       return 0;
+}
+
+static struct irq_host_ops cpm2_pic_host_ops = {
+       .match = cpm2_pic_host_match,
+       .map = cpm2_pic_host_map,
+       .unmap = cpm2_host_unmap,
+       .xlate = cpm2_pic_host_xlate,
+};
+
+void cpm2_pic_init(struct device_node *node)
+{
+       int i;
+
+       /* Clear the CPM IRQ controller, in case it has any bits set
+        * from the bootloader
+        */
+
+       /* Mask out everything */
+
+       cpm2_intctl->ic_simrh = 0x00000000;
+       cpm2_intctl->ic_simrl = 0x00000000;
+
+       wmb();
+
+       /* Ack everything */
+       cpm2_intctl->ic_sipnrh = 0xffffffff;
+       cpm2_intctl->ic_sipnrl = 0xffffffff;
+       wmb();
+
+       /* Dummy read of the vector */
+       i = cpm2_intctl->ic_sivec;
+       rmb();
+
+       /* Initialize the default interrupt mapping priorities,
+        * in case the boot rom changed something on us.
+        */
+       cpm2_intctl->ic_sicr = 0;
+       cpm2_intctl->ic_scprrh = 0x05309770;
+       cpm2_intctl->ic_scprrl = 0x05309770;
+
+       /* create a legacy host */
+       if (node)
+               cpm2_pic_node = of_node_get(node);
+
+       cpm2_pic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 64, &cpm2_pic_host_ops, 64);
+       if (cpm2_pic_host == NULL) {
+               printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
+               return;
+       }
+}
diff --git a/arch/powerpc/sysdev/cpm2_pic.h b/arch/powerpc/sysdev/cpm2_pic.h
new file mode 100644 (file)
index 0000000..3c513e5
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef _PPC_KERNEL_CPM2_H
+#define _PPC_KERNEL_CPM2_H
+
+extern intctl_cpm2_t *cpm2_intctl;
+
+extern unsigned int cpm2_get_irq(struct pt_regs *regs);
+
+extern void cpm2_pic_init(struct device_node*);
+
+#endif /* _PPC_KERNEL_CPM2_H */
index 92ba378b7990a44fa4ca24f004d10cca7a30218a..7d759f1c26b19fe61a5df4813861b18b3071d509 100644 (file)
@@ -3,6 +3,9 @@
  *
  * Maintained by Kumar Gala (see MAINTAINERS for contact information)
  *
+ * 2006 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.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
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/fsl_devices.h>
+#include <linux/fs_enet_pd.h>
+#include <linux/fs_uart_pd.h>
 
 #include <asm/system.h>
 #include <asm/atomic.h>
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <asm/time.h>
 #include <asm/prom.h>
 #include <sysdev/fsl_soc.h>
 #include <mm/mmu_decl.h>
+#include <asm/cpm2.h>
 
+extern void init_fcc_ioports(struct fs_platform_info*);
+extern void init_scc_ioports(struct fs_uart_platform_info*);
 static phys_addr_t immrbase = -1;
 
 phys_addr_t get_immrbase(void)
@@ -42,7 +51,9 @@ phys_addr_t get_immrbase(void)
        if (soc) {
                unsigned int size;
                const void *prop = get_property(soc, "reg", &size);
-               immrbase = of_translate_address(soc, prop);
+
+               if (prop)
+                       immrbase = of_translate_address(soc, prop);
                of_node_put(soc);
        };
 
@@ -51,6 +62,59 @@ phys_addr_t get_immrbase(void)
 
 EXPORT_SYMBOL(get_immrbase);
 
+#ifdef CONFIG_CPM2
+
+static u32 brgfreq = -1;
+
+u32 get_brgfreq(void)
+{
+       struct device_node *node;
+
+       if (brgfreq != -1)
+               return brgfreq;
+
+       node = of_find_node_by_type(NULL, "cpm");
+       if (node) {
+               unsigned int size;
+               const unsigned int *prop = get_property(node, "brg-frequency",
+                                       &size);
+
+               if (prop)
+                       brgfreq = *prop;
+               of_node_put(node);
+       };
+
+       return brgfreq;
+}
+
+EXPORT_SYMBOL(get_brgfreq);
+
+static u32 fs_baudrate = -1;
+
+u32 get_baudrate(void)
+{
+       struct device_node *node;
+
+       if (fs_baudrate != -1)
+               return fs_baudrate;
+
+       node = of_find_node_by_type(NULL, "serial");
+       if (node) {
+               unsigned int size;
+               const unsigned int *prop = get_property(node, "current-speed",
+                               &size);
+
+               if (prop)
+                       fs_baudrate = *prop;
+               of_node_put(node);
+       };
+
+       return fs_baudrate;
+}
+
+EXPORT_SYMBOL(get_baudrate);
+#endif /* CONFIG_CPM2 */
+
 static int __init gfar_mdio_of_init(void)
 {
        struct device_node *np;
@@ -85,8 +149,11 @@ static int __init gfar_mdio_of_init(void)
                        mdio_data.irq[k] = -1;
 
                while ((child = of_get_next_child(np, child)) != NULL) {
-                       const u32 *id = get_property(child, "reg", NULL);
-                       mdio_data.irq[*id] = irq_of_parse_and_map(child, 0);
+                       int irq = irq_of_parse_and_map(child, 0);
+                       if (irq != NO_IRQ) {
+                               const u32 *id = get_property(child, "reg", NULL);
+                               mdio_data.irq[*id] = irq;
+                       }
                }
 
                ret =
@@ -128,7 +195,7 @@ static int __init gfar_of_init(void)
                const char *model;
                const void *mac_addr;
                const phandle *ph;
-               int n_res = 1;
+               int n_res = 2;
 
                memset(r, 0, sizeof(r));
                memset(&gfar_data, 0, sizeof(gfar_data));
@@ -159,7 +226,7 @@ static int __init gfar_of_init(void)
 
                gfar_dev =
                    platform_device_register_simple("fsl-gianfar", i, &r[0],
-                                                   n_res + 1);
+                                                   n_res);
 
                if (IS_ERR(gfar_dev)) {
                        ret = PTR_ERR(gfar_dev);
@@ -478,3 +545,255 @@ err:
 }
 
 arch_initcall(fsl_usb_of_init);
+
+#ifdef CONFIG_CPM2
+
+static const char fcc_regs[] = "fcc_regs";
+static const char fcc_regs_c[] = "fcc_regs_c";
+static const char fcc_pram[] = "fcc_pram";
+static char bus_id[9][BUS_ID_SIZE];
+
+static int __init fs_enet_of_init(void)
+{
+       struct device_node *np;
+       unsigned int i;
+       struct platform_device *fs_enet_dev;
+       struct resource res;
+       int ret;
+
+       for (np = NULL, i = 0;
+            (np = of_find_compatible_node(np, "network", "fs_enet")) != NULL;
+            i++) {
+               struct resource r[4];
+               struct device_node *phy, *mdio;
+               struct fs_platform_info fs_enet_data;
+               const unsigned int *id, *phy_addr, phy_irq;
+               const void *mac_addr;
+               const phandle *ph;
+               const char *model;
+
+               memset(r, 0, sizeof(r));
+               memset(&fs_enet_data, 0, sizeof(fs_enet_data));
+
+               ret = of_address_to_resource(np, 0, &r[0]);
+               if (ret)
+                       goto err;
+               r[0].name = fcc_regs;
+
+               ret = of_address_to_resource(np, 1, &r[1]);
+               if (ret)
+                       goto err;
+               r[1].name = fcc_pram;
+
+               ret = of_address_to_resource(np, 2, &r[2]);
+               if (ret)
+                       goto err;
+               r[2].name = fcc_regs_c;
+               fs_enet_data.fcc_regs_c = r[2].start;
+
+               r[3].start = r[3].end = irq_of_parse_and_map(np, 0);
+               r[3].flags = IORESOURCE_IRQ;
+
+               fs_enet_dev =
+                   platform_device_register_simple("fsl-cpm-fcc", i, &r[0], 4);
+
+               if (IS_ERR(fs_enet_dev)) {
+                       ret = PTR_ERR(fs_enet_dev);
+                       goto err;
+               }
+
+               model = get_property(np, "model", NULL);
+               if (model == NULL) {
+                       ret = -ENODEV;
+                       goto unreg;
+               }
+
+               mac_addr = get_property(np, "mac-address", NULL);
+               memcpy(fs_enet_data.macaddr, mac_addr, 6);
+
+               ph = get_property(np, "phy-handle", NULL);
+               phy = of_find_node_by_phandle(*ph);
+
+               if (phy == NULL) {
+                       ret = -ENODEV;
+                       goto unreg;
+               }
+
+               phy_addr = get_property(phy, "reg", NULL);
+               fs_enet_data.phy_addr = *phy_addr;
+
+               phy_irq = get_property(phy, "interrupts", NULL);
+
+               id = get_property(np, "device-id", NULL);
+               fs_enet_data.fs_no = *id;
+               strcpy(fs_enet_data.fs_type, model);
+
+               mdio = of_get_parent(phy);
+                ret = of_address_to_resource(mdio, 0, &res);
+                if (ret) {
+                        of_node_put(phy);
+                        of_node_put(mdio);
+                        goto unreg;
+                }
+
+               fs_enet_data.clk_rx = *((u32 *) get_property(np, "rx-clock", NULL));
+               fs_enet_data.clk_tx = *((u32 *) get_property(np, "tx-clock", NULL));
+
+               if (strstr(model, "FCC")) {
+                       int fcc_index = *id - 1;
+                       unsigned char* mdio_bb_prop;
+
+                       fs_enet_data.dpram_offset = (u32)cpm_dpram_addr(0);
+                       fs_enet_data.rx_ring = 32;
+                       fs_enet_data.tx_ring = 32;
+                       fs_enet_data.rx_copybreak = 240;
+                       fs_enet_data.use_napi = 0;
+                       fs_enet_data.napi_weight = 17;
+                       fs_enet_data.mem_offset = FCC_MEM_OFFSET(fcc_index);
+                       fs_enet_data.cp_page = CPM_CR_FCC_PAGE(fcc_index);
+                       fs_enet_data.cp_block = CPM_CR_FCC_SBLOCK(fcc_index);
+
+                       snprintf((char*)&bus_id[(*id)], BUS_ID_SIZE, "%x:%02x",
+                                                       (u32)res.start, fs_enet_data.phy_addr);
+                       fs_enet_data.bus_id = (char*)&bus_id[(*id)];
+                       fs_enet_data.init_ioports = init_fcc_ioports;
+
+                       mdio_bb_prop = get_property(phy, "bitbang", NULL);
+                       if (mdio_bb_prop) {
+                               struct platform_device *fs_enet_mdio_bb_dev;
+                               struct fs_mii_bb_platform_info fs_enet_mdio_bb_data;
+
+                               fs_enet_mdio_bb_dev =
+                                       platform_device_register_simple("fsl-bb-mdio",
+                                                       i, NULL, 0);
+                               memset(&fs_enet_mdio_bb_data, 0,
+                                               sizeof(struct fs_mii_bb_platform_info));
+                               fs_enet_mdio_bb_data.mdio_dat.bit =
+                                       mdio_bb_prop[0];
+                               fs_enet_mdio_bb_data.mdio_dir.bit =
+                                       mdio_bb_prop[1];
+                               fs_enet_mdio_bb_data.mdc_dat.bit =
+                                       mdio_bb_prop[2];
+                               fs_enet_mdio_bb_data.mdio_port =
+                                       mdio_bb_prop[3];
+                               fs_enet_mdio_bb_data.mdc_port =
+                                       mdio_bb_prop[4];
+                               fs_enet_mdio_bb_data.delay =
+                                       mdio_bb_prop[5];
+
+                               fs_enet_mdio_bb_data.irq[0] = phy_irq[0];
+                               fs_enet_mdio_bb_data.irq[1] = -1;
+                               fs_enet_mdio_bb_data.irq[2] = -1;
+                               fs_enet_mdio_bb_data.irq[3] = phy_irq[0];
+                               fs_enet_mdio_bb_data.irq[31] = -1;
+
+                               fs_enet_mdio_bb_data.mdio_dat.offset =
+                                       (u32)&cpm2_immr->im_ioport.iop_pdatc;
+                               fs_enet_mdio_bb_data.mdio_dir.offset =
+                                       (u32)&cpm2_immr->im_ioport.iop_pdirc;
+                               fs_enet_mdio_bb_data.mdc_dat.offset =
+                                       (u32)&cpm2_immr->im_ioport.iop_pdatc;
+
+                               ret = platform_device_add_data(
+                                               fs_enet_mdio_bb_dev,
+                                               &fs_enet_mdio_bb_data,
+                                               sizeof(struct fs_mii_bb_platform_info));
+                               if (ret)
+                                       goto unreg;
+                       }
+                       
+                       of_node_put(phy);
+                       of_node_put(mdio);
+
+                       ret = platform_device_add_data(fs_enet_dev, &fs_enet_data,
+                                                    sizeof(struct
+                                                           fs_platform_info));
+               if (ret)
+                       goto unreg;
+       }
+       return 0;
+
+unreg:
+       platform_device_unregister(fs_enet_dev);
+err:
+       return ret;
+}
+
+arch_initcall(fs_enet_of_init);
+
+static const char scc_regs[] = "regs";
+static const char scc_pram[] = "pram";
+
+static int __init cpm_uart_of_init(void)
+{
+       struct device_node *np;
+       unsigned int i;
+       struct platform_device *cpm_uart_dev;
+       int ret;
+
+       for (np = NULL, i = 0;
+            (np = of_find_compatible_node(np, "serial", "cpm_uart")) != NULL;
+            i++) {
+               struct resource r[3];
+               struct fs_uart_platform_info cpm_uart_data;
+               const int *id;
+               const char *model;
+
+               memset(r, 0, sizeof(r));
+               memset(&cpm_uart_data, 0, sizeof(cpm_uart_data));
+
+               ret = of_address_to_resource(np, 0, &r[0]);
+               if (ret)
+                       goto err;
+
+               r[0].name = scc_regs;
+
+               ret = of_address_to_resource(np, 1, &r[1]);
+               if (ret)
+                       goto err;
+               r[1].name = scc_pram;
+
+               r[2].start = r[2].end = irq_of_parse_and_map(np, 0);
+               r[2].flags = IORESOURCE_IRQ;
+
+               cpm_uart_dev =
+                   platform_device_register_simple("fsl-cpm-scc:uart", i, &r[0], 3);
+
+               if (IS_ERR(cpm_uart_dev)) {
+                       ret = PTR_ERR(cpm_uart_dev);
+                       goto err;
+               }
+
+               id = get_property(np, "device-id", NULL);
+               cpm_uart_data.fs_no = *id;
+
+               model = (char*)get_property(np, "model", NULL);
+               strcpy(cpm_uart_data.fs_type, model);
+
+               cpm_uart_data.uart_clk = ppc_proc_freq;
+
+               cpm_uart_data.tx_num_fifo = 4;
+               cpm_uart_data.tx_buf_size = 32;
+               cpm_uart_data.rx_num_fifo = 4;
+               cpm_uart_data.rx_buf_size = 32;
+               cpm_uart_data.clk_rx = *((u32 *) get_property(np, "rx-clock", NULL));
+               cpm_uart_data.clk_tx = *((u32 *) get_property(np, "tx-clock", NULL));
+
+               ret =
+                   platform_device_add_data(cpm_uart_dev, &cpm_uart_data,
+                                            sizeof(struct
+                                                   fs_uart_platform_info));
+               if (ret)
+                       goto unreg;
+       }
+
+       return 0;
+
+unreg:
+       platform_device_unregister(cpm_uart_dev);
+err:
+       return ret;
+}
+
+arch_initcall(cpm_uart_of_init);
+#endif /* CONFIG_CPM2 */
index 5a3dd480d2fd8eff791e62ae40e12de8a553b22a..04e145b5fc324066ebb52d2f895d8538270c3506 100644 (file)
@@ -5,6 +5,8 @@
 #include <asm/mmu.h>
 
 extern phys_addr_t get_immrbase(void);
+extern u32 get_brgfreq(void);
+extern u32 get_baudrate(void);
 
 #endif
 #endif
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;
                }
        }
diff --git a/arch/powerpc/sysdev/qe_lib/Kconfig b/arch/powerpc/sysdev/qe_lib/Kconfig
new file mode 100644 (file)
index 0000000..a725e80
--- /dev/null
@@ -0,0 +1,30 @@
+#
+# QE Communication options
+#
+
+menu "QE Options"
+       depends on QUICC_ENGINE
+
+config UCC_SLOW
+       bool "UCC Slow Protocols Support"
+       default n
+       select UCC
+       help
+         This option provides qe_lib support to UCC slow
+         protocols: UART, BISYNC, QMC
+
+config UCC_FAST
+       bool "UCC Fast Protocols Support"
+       default n
+       select UCC
+       select UCC_SLOW
+       help
+         This option provides qe_lib support to UCC fast
+         protocols: HDLC, Ethernet, ATM, transparent
+
+config UCC
+       bool
+       default y if UCC_FAST || UCC_SLOW
+
+endmenu
+
diff --git a/arch/powerpc/sysdev/qe_lib/Makefile b/arch/powerpc/sysdev/qe_lib/Makefile
new file mode 100644 (file)
index 0000000..874fe1a
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# Makefile for the linux ppc-specific parts of QE
+#
+obj-$(CONFIG_QUICC_ENGINE)+= qe.o qe_ic.o qe_io.o
+
+obj-$(CONFIG_UCC)      += ucc.o
+obj-$(CONFIG_UCC_SLOW) += ucc_slow.o
+obj-$(CONFIG_UCC_FAST) += ucc_fast.o
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
new file mode 100644 (file)
index 0000000..2bae632
--- /dev/null
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
+ *
+ * Authors:    Shlomi Gridish <gridish@freescale.com>
+ *             Li Yang <leoli@freescale.com>
+ * Based on cpm2_common.c from Dan Malek (dmalek@jlc.net)
+ *
+ * Description:
+ * General Purpose functions for the global management of the
+ * QUICC Engine (QE).
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/bootmem.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <asm/irq.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/immap_qe.h>
+#include <asm/qe.h>
+#include <asm/prom.h>
+#include <asm/rheap.h>
+
+static void qe_snums_init(void);
+static void qe_muram_init(void);
+static int qe_sdma_init(void);
+
+static DEFINE_SPINLOCK(qe_lock);
+
+/* QE snum state */
+enum qe_snum_state {
+       QE_SNUM_STATE_USED,
+       QE_SNUM_STATE_FREE
+};
+
+/* QE snum */
+struct qe_snum {
+       u8 num;
+       enum qe_snum_state state;
+};
+
+/* We allocate this here because it is used almost exclusively for
+ * the communication processor devices.
+ */
+struct qe_immap *qe_immr = NULL;
+EXPORT_SYMBOL(qe_immr);
+
+static struct qe_snum snums[QE_NUM_OF_SNUM];   /* Dynamically allocated SNUMs */
+
+static phys_addr_t qebase = -1;
+
+phys_addr_t get_qe_base(void)
+{
+       struct device_node *qe;
+
+       if (qebase != -1)
+               return qebase;
+
+       qe = of_find_node_by_type(NULL, "qe");
+       if (qe) {
+               unsigned int size;
+               const void *prop = get_property(qe, "reg", &size);
+               qebase = of_translate_address(qe, prop);
+               of_node_put(qe);
+       };
+
+       return qebase;
+}
+
+EXPORT_SYMBOL(get_qe_base);
+
+void qe_reset(void)
+{
+       if (qe_immr == NULL)
+               qe_immr = ioremap(get_qe_base(), QE_IMMAP_SIZE);
+
+       qe_snums_init();
+
+       qe_issue_cmd(QE_RESET, QE_CR_SUBBLOCK_INVALID,
+                    QE_CR_PROTOCOL_UNSPECIFIED, 0);
+
+       /* Reclaim the MURAM memory for our use. */
+       qe_muram_init();
+
+       if (qe_sdma_init())
+               panic("sdma init failed!");
+}
+
+int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input)
+{
+       unsigned long flags;
+       u8 mcn_shift = 0, dev_shift = 0;
+
+       spin_lock_irqsave(&qe_lock, flags);
+       if (cmd == QE_RESET) {
+               out_be32(&qe_immr->cp.cecr, (u32) (cmd | QE_CR_FLG));
+       } else {
+               if (cmd == QE_ASSIGN_PAGE) {
+                       /* Here device is the SNUM, not sub-block */
+                       dev_shift = QE_CR_SNUM_SHIFT;
+               } else if (cmd == QE_ASSIGN_RISC) {
+                       /* Here device is the SNUM, and mcnProtocol is
+                        * e_QeCmdRiscAssignment value */
+                       dev_shift = QE_CR_SNUM_SHIFT;
+                       mcn_shift = QE_CR_MCN_RISC_ASSIGN_SHIFT;
+               } else {
+                       if (device == QE_CR_SUBBLOCK_USB)
+                               mcn_shift = QE_CR_MCN_USB_SHIFT;
+                       else
+                               mcn_shift = QE_CR_MCN_NORMAL_SHIFT;
+               }
+
+               out_be32(&qe_immr->cp.cecdr,
+                        immrbar_virt_to_phys((void *)cmd_input));
+               out_be32(&qe_immr->cp.cecr,
+                        (cmd | QE_CR_FLG | ((u32) device << dev_shift) | (u32)
+                         mcn_protocol << mcn_shift));
+       }
+
+       /* wait for the QE_CR_FLG to clear */
+       while(in_be32(&qe_immr->cp.cecr) & QE_CR_FLG)
+               cpu_relax();
+       spin_unlock_irqrestore(&qe_lock, flags);
+
+       return 0;
+}
+EXPORT_SYMBOL(qe_issue_cmd);
+
+/* Set a baud rate generator. This needs lots of work. There are
+ * 16 BRGs, which can be connected to the QE channels or output
+ * as clocks. The BRGs are in two different block of internal
+ * memory mapped space.
+ * The baud rate clock is the system clock divided by something.
+ * It was set up long ago during the initial boot phase and is
+ * is given to us.
+ * Baud rate clocks are zero-based in the driver code (as that maps
+ * to port numbers). Documentation uses 1-based numbering.
+ */
+static unsigned int brg_clk = 0;
+
+unsigned int get_brg_clk(void)
+{
+       struct device_node *qe;
+       if (brg_clk)
+               return brg_clk;
+
+       qe = of_find_node_by_type(NULL, "qe");
+       if (qe) {
+               unsigned int size;
+               const u32 *prop = get_property(qe, "brg-frequency", &size);
+               brg_clk = *prop;
+               of_node_put(qe);
+       };
+       return brg_clk;
+}
+
+/* This function is used by UARTS, or anything else that uses a 16x
+ * oversampled clock.
+ */
+void qe_setbrg(u32 brg, u32 rate)
+{
+       volatile u32 *bp;
+       u32 divisor, tempval;
+       int div16 = 0;
+
+       bp = &qe_immr->brg.brgc1;
+       bp += brg;
+
+       divisor = (get_brg_clk() / rate);
+       if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
+               div16 = 1;
+               divisor /= 16;
+       }
+
+       tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | QE_BRGC_ENABLE;
+       if (div16)
+               tempval |= QE_BRGC_DIV16;
+
+       out_be32(bp, tempval);
+}
+
+/* Initialize SNUMs (thread serial numbers) according to
+ * QE Module Control chapter, SNUM table
+ */
+static void qe_snums_init(void)
+{
+       int i;
+       static const u8 snum_init[] = {
+               0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
+               0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
+               0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9,
+               0xD8, 0xD9, 0xE8, 0xE9,
+       };
+
+       for (i = 0; i < QE_NUM_OF_SNUM; i++) {
+               snums[i].num = snum_init[i];
+               snums[i].state = QE_SNUM_STATE_FREE;
+       }
+}
+
+int qe_get_snum(void)
+{
+       unsigned long flags;
+       int snum = -EBUSY;
+       int i;
+
+       spin_lock_irqsave(&qe_lock, flags);
+       for (i = 0; i < QE_NUM_OF_SNUM; i++) {
+               if (snums[i].state == QE_SNUM_STATE_FREE) {
+                       snums[i].state = QE_SNUM_STATE_USED;
+                       snum = snums[i].num;
+                       break;
+               }
+       }
+       spin_unlock_irqrestore(&qe_lock, flags);
+
+       return snum;
+}
+EXPORT_SYMBOL(qe_get_snum);
+
+void qe_put_snum(u8 snum)
+{
+       int i;
+
+       for (i = 0; i < QE_NUM_OF_SNUM; i++) {
+               if (snums[i].num == snum) {
+                       snums[i].state = QE_SNUM_STATE_FREE;
+                       break;
+               }
+       }
+}
+EXPORT_SYMBOL(qe_put_snum);
+
+static int qe_sdma_init(void)
+{
+       struct sdma *sdma = &qe_immr->sdma;
+       u32 sdma_buf_offset;
+
+       if (!sdma)
+               return -ENODEV;
+
+       /* allocate 2 internal temporary buffers (512 bytes size each) for
+        * the SDMA */
+       sdma_buf_offset = qe_muram_alloc(512 * 2, 64);
+       if (IS_MURAM_ERR(sdma_buf_offset))
+               return -ENOMEM;
+
+       out_be32(&sdma->sdebcr, sdma_buf_offset & QE_SDEBCR_BA_MASK);
+       out_be32(&sdma->sdmr, (QE_SDMR_GLB_1_MSK | (0x1 >>
+                                       QE_SDMR_CEN_SHIFT)));
+
+       return 0;
+}
+
+/*
+ * muram_alloc / muram_free bits.
+ */
+static DEFINE_SPINLOCK(qe_muram_lock);
+
+/* 16 blocks should be enough to satisfy all requests
+ * until the memory subsystem goes up... */
+static rh_block_t qe_boot_muram_rh_block[16];
+static rh_info_t qe_muram_info;
+
+static void qe_muram_init(void)
+{
+       struct device_node *np;
+       u32 address;
+       u64 size;
+       unsigned int flags;
+
+       /* initialize the info header */
+       rh_init(&qe_muram_info, 1,
+               sizeof(qe_boot_muram_rh_block) /
+               sizeof(qe_boot_muram_rh_block[0]), qe_boot_muram_rh_block);
+
+       /* Attach the usable muram area */
+       /* XXX: This is a subset of the available muram. It
+        * varies with the processor and the microcode patches activated.
+        */
+       if ((np = of_find_node_by_name(NULL, "data-only")) != NULL) {
+               address = *of_get_address(np, 0, &size, &flags);
+               of_node_put(np);
+               rh_attach_region(&qe_muram_info,
+                       (void *)address, (int)size);
+       }
+}
+
+/* This function returns an index into the MURAM area.
+ */
+u32 qe_muram_alloc(u32 size, u32 align)
+{
+       void *start;
+       unsigned long flags;
+
+       spin_lock_irqsave(&qe_muram_lock, flags);
+       start = rh_alloc_align(&qe_muram_info, size, align, "QE");
+       spin_unlock_irqrestore(&qe_muram_lock, flags);
+
+       return (u32) start;
+}
+EXPORT_SYMBOL(qe_muram_alloc);
+
+int qe_muram_free(u32 offset)
+{
+       int ret;
+       unsigned long flags;
+
+       spin_lock_irqsave(&qe_muram_lock, flags);
+       ret = rh_free(&qe_muram_info, (void *)offset);
+       spin_unlock_irqrestore(&qe_muram_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(qe_muram_free);
+
+/* not sure if this is ever needed */
+u32 qe_muram_alloc_fixed(u32 offset, u32 size)
+{
+       void *start;
+       unsigned long flags;
+
+       spin_lock_irqsave(&qe_muram_lock, flags);
+       start = rh_alloc_fixed(&qe_muram_info, (void *)offset, size, "commproc");
+       spin_unlock_irqrestore(&qe_muram_lock, flags);
+
+       return (u32) start;
+}
+EXPORT_SYMBOL(qe_muram_alloc_fixed);
+
+void qe_muram_dump(void)
+{
+       rh_dump(&qe_muram_info);
+}
+EXPORT_SYMBOL(qe_muram_dump);
+
+void *qe_muram_addr(u32 offset)
+{
+       return (void *)&qe_immr->muram[offset];
+}
+EXPORT_SYMBOL(qe_muram_addr);
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
new file mode 100644 (file)
index 0000000..c229d07
--- /dev/null
@@ -0,0 +1,555 @@
+/*
+ * arch/powerpc/sysdev/qe_lib/qe_ic.c
+ *
+ * Copyright (C) 2006 Freescale Semicondutor, Inc.  All rights reserved.
+ *
+ * Author: Li Yang <leoli@freescale.com>
+ * Based on code from Shlomi Gridish <gridish@freescale.com>
+ *
+ * QUICC ENGINE Interrupt Controller
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <linux/slab.h>
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/sysdev.h>
+#include <linux/device.h>
+#include <linux/bootmem.h>
+#include <linux/spinlock.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/qe_ic.h>
+
+#include "qe_ic.h"
+
+static DEFINE_SPINLOCK(qe_ic_lock);
+
+static struct qe_ic_info qe_ic_info[] = {
+       [1] = {
+              .mask = 0x00008000,
+              .mask_reg = QEIC_CIMR,
+              .pri_code = 0,
+              .pri_reg = QEIC_CIPWCC,
+              },
+       [2] = {
+              .mask = 0x00004000,
+              .mask_reg = QEIC_CIMR,
+              .pri_code = 1,
+              .pri_reg = QEIC_CIPWCC,
+              },
+       [3] = {
+              .mask = 0x00002000,
+              .mask_reg = QEIC_CIMR,
+              .pri_code = 2,
+              .pri_reg = QEIC_CIPWCC,
+              },
+       [10] = {
+               .mask = 0x00000040,
+               .mask_reg = QEIC_CIMR,
+               .pri_code = 1,
+               .pri_reg = QEIC_CIPZCC,
+               },
+       [11] = {
+               .mask = 0x00000020,
+               .mask_reg = QEIC_CIMR,
+               .pri_code = 2,
+               .pri_reg = QEIC_CIPZCC,
+               },
+       [12] = {
+               .mask = 0x00000010,
+               .mask_reg = QEIC_CIMR,
+               .pri_code = 3,
+               .pri_reg = QEIC_CIPZCC,
+               },
+       [13] = {
+               .mask = 0x00000008,
+               .mask_reg = QEIC_CIMR,
+               .pri_code = 4,
+               .pri_reg = QEIC_CIPZCC,
+               },
+       [14] = {
+               .mask = 0x00000004,
+               .mask_reg = QEIC_CIMR,
+               .pri_code = 5,
+               .pri_reg = QEIC_CIPZCC,
+               },
+       [15] = {
+               .mask = 0x00000002,
+               .mask_reg = QEIC_CIMR,
+               .pri_code = 6,
+               .pri_reg = QEIC_CIPZCC,
+               },
+       [20] = {
+               .mask = 0x10000000,
+               .mask_reg = QEIC_CRIMR,
+               .pri_code = 3,
+               .pri_reg = QEIC_CIPRTA,
+               },
+       [25] = {
+               .mask = 0x00800000,
+               .mask_reg = QEIC_CRIMR,
+               .pri_code = 0,
+               .pri_reg = QEIC_CIPRTB,
+               },
+       [26] = {
+               .mask = 0x00400000,
+               .mask_reg = QEIC_CRIMR,
+               .pri_code = 1,
+               .pri_reg = QEIC_CIPRTB,
+               },
+       [27] = {
+               .mask = 0x00200000,
+               .mask_reg = QEIC_CRIMR,
+               .pri_code = 2,
+               .pri_reg = QEIC_CIPRTB,
+               },
+       [28] = {
+               .mask = 0x00100000,
+               .mask_reg = QEIC_CRIMR,
+               .pri_code = 3,
+               .pri_reg = QEIC_CIPRTB,
+               },
+       [32] = {
+               .mask = 0x80000000,
+               .mask_reg = QEIC_CIMR,
+               .pri_code = 0,
+               .pri_reg = QEIC_CIPXCC,
+               },
+       [33] = {
+               .mask = 0x40000000,
+               .mask_reg = QEIC_CIMR,
+               .pri_code = 1,
+               .pri_reg = QEIC_CIPXCC,
+               },
+       [34] = {
+               .mask = 0x20000000,
+               .mask_reg = QEIC_CIMR,
+               .pri_code = 2,
+               .pri_reg = QEIC_CIPXCC,
+               },
+       [35] = {
+               .mask = 0x10000000,
+               .mask_reg = QEIC_CIMR,
+               .pri_code = 3,
+               .pri_reg = QEIC_CIPXCC,
+               },
+       [36] = {
+               .mask = 0x08000000,
+               .mask_reg = QEIC_CIMR,
+               .pri_code = 4,
+               .pri_reg = QEIC_CIPXCC,
+               },
+       [40] = {
+               .mask = 0x00800000,
+               .mask_reg = QEIC_CIMR,
+               .pri_code = 0,
+               .pri_reg = QEIC_CIPYCC,
+               },
+       [41] = {
+               .mask = 0x00400000,
+               .mask_reg = QEIC_CIMR,
+               .pri_code = 1,
+               .pri_reg = QEIC_CIPYCC,
+               },
+       [42] = {
+               .mask = 0x00200000,
+               .mask_reg = QEIC_CIMR,
+               .pri_code = 2,
+               .pri_reg = QEIC_CIPYCC,
+               },
+       [43] = {
+               .mask = 0x00100000,
+               .mask_reg = QEIC_CIMR,
+               .pri_code = 3,
+               .pri_reg = QEIC_CIPYCC,
+               },
+};
+
+static inline u32 qe_ic_read(volatile __be32  __iomem * base, unsigned int reg)
+{
+       return in_be32(base + (reg >> 2));
+}
+
+static inline void qe_ic_write(volatile __be32  __iomem * base, unsigned int reg,
+                              u32 value)
+{
+       out_be32(base + (reg >> 2), value);
+}
+
+static inline struct qe_ic *qe_ic_from_irq(unsigned int virq)
+{
+       return irq_desc[virq].chip_data;
+}
+
+#define virq_to_hw(virq)       ((unsigned int)irq_map[virq].hwirq)
+
+static void qe_ic_unmask_irq(unsigned int virq)
+{
+       struct qe_ic *qe_ic = qe_ic_from_irq(virq);
+       unsigned int src = virq_to_hw(virq);
+       unsigned long flags;
+       u32 temp;
+
+       spin_lock_irqsave(&qe_ic_lock, flags);
+
+       temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
+       qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
+                   temp | qe_ic_info[src].mask);
+
+       spin_unlock_irqrestore(&qe_ic_lock, flags);
+}
+
+static void qe_ic_mask_irq(unsigned int virq)
+{
+       struct qe_ic *qe_ic = qe_ic_from_irq(virq);
+       unsigned int src = virq_to_hw(virq);
+       unsigned long flags;
+       u32 temp;
+
+       spin_lock_irqsave(&qe_ic_lock, flags);
+
+       temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
+       qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
+                   temp & ~qe_ic_info[src].mask);
+
+       spin_unlock_irqrestore(&qe_ic_lock, flags);
+}
+
+static void qe_ic_mask_irq_and_ack(unsigned int virq)
+{
+       struct qe_ic *qe_ic = qe_ic_from_irq(virq);
+       unsigned int src = virq_to_hw(virq);
+       unsigned long flags;
+       u32 temp;
+
+       spin_lock_irqsave(&qe_ic_lock, flags);
+
+       temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
+       qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
+                   temp & ~qe_ic_info[src].mask);
+
+       /* There is nothing to do for ack here, ack is handled in ISR */
+
+       spin_unlock_irqrestore(&qe_ic_lock, flags);
+}
+
+static struct irq_chip qe_ic_irq_chip = {
+       .typename = " QEIC  ",
+       .unmask = qe_ic_unmask_irq,
+       .mask = qe_ic_mask_irq,
+       .mask_ack = qe_ic_mask_irq_and_ack,
+};
+
+static int qe_ic_host_match(struct irq_host *h, struct device_node *node)
+{
+       struct qe_ic *qe_ic = h->host_data;
+
+       /* Exact match, unless qe_ic node is NULL */
+       return qe_ic->of_node == NULL || qe_ic->of_node == node;
+}
+
+static int qe_ic_host_map(struct irq_host *h, unsigned int virq,
+                         irq_hw_number_t hw)
+{
+       struct qe_ic *qe_ic = h->host_data;
+       struct irq_chip *chip;
+
+       if (qe_ic_info[hw].mask == 0) {
+               printk(KERN_ERR "Can't map reserved IRQ \n");
+               return -EINVAL;
+       }
+       /* Default chip */
+       chip = &qe_ic->hc_irq;
+
+       set_irq_chip_data(virq, qe_ic);
+       get_irq_desc(virq)->status |= IRQ_LEVEL;
+
+       set_irq_chip_and_handler(virq, chip, handle_level_irq);
+
+       return 0;
+}
+
+static int qe_ic_host_xlate(struct irq_host *h, struct device_node *ct,
+                           u32 * intspec, unsigned int intsize,
+                           irq_hw_number_t * out_hwirq,
+                           unsigned int *out_flags)
+{
+       *out_hwirq = intspec[0];
+       if (intsize > 1)
+               *out_flags = intspec[1];
+       else
+               *out_flags = IRQ_TYPE_NONE;
+       return 0;
+}
+
+static struct irq_host_ops qe_ic_host_ops = {
+       .match = qe_ic_host_match,
+       .map = qe_ic_host_map,
+       .xlate = qe_ic_host_xlate,
+};
+
+/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
+unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic, struct pt_regs *regs)
+{
+       int irq;
+
+       BUG_ON(qe_ic == NULL);
+
+       /* get the interrupt source vector. */
+       irq = qe_ic_read(qe_ic->regs, QEIC_CIVEC) >> 26;
+
+       if (irq == 0)
+               return NO_IRQ;
+
+       return irq_linear_revmap(qe_ic->irqhost, irq);
+}
+
+/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
+unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic, struct pt_regs *regs)
+{
+       int irq;
+
+       BUG_ON(qe_ic == NULL);
+
+       /* get the interrupt source vector. */
+       irq = qe_ic_read(qe_ic->regs, QEIC_CHIVEC) >> 26;
+
+       if (irq == 0)
+               return NO_IRQ;
+
+       return irq_linear_revmap(qe_ic->irqhost, irq);
+}
+
+/* FIXME: We mask all the QE Low interrupts while handling.  We should
+ * let other interrupt come in, but BAD interrupts are generated */
+void fastcall qe_ic_cascade_low(unsigned int irq, struct irq_desc *desc,
+                               struct pt_regs *regs)
+{
+       struct qe_ic *qe_ic = desc->handler_data;
+       struct irq_chip *chip = irq_desc[irq].chip;
+
+       unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic, regs);
+
+       chip->mask_ack(irq);
+       if (cascade_irq != NO_IRQ)
+               generic_handle_irq(cascade_irq, regs);
+       chip->unmask(irq);
+}
+
+/* FIXME: We mask all the QE High interrupts while handling.  We should
+ * let other interrupt come in, but BAD interrupts are generated */
+void fastcall qe_ic_cascade_high(unsigned int irq, struct irq_desc *desc,
+                                struct pt_regs *regs)
+{
+       struct qe_ic *qe_ic = desc->handler_data;
+       struct irq_chip *chip = irq_desc[irq].chip;
+
+       unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic, regs);
+
+       chip->mask_ack(irq);
+       if (cascade_irq != NO_IRQ)
+               generic_handle_irq(cascade_irq, regs);
+       chip->unmask(irq);
+}
+
+void __init qe_ic_init(struct device_node *node, unsigned int flags)
+{
+       struct qe_ic *qe_ic;
+       struct resource res;
+       u32 temp = 0, ret, high_active = 0;
+
+       qe_ic = alloc_bootmem(sizeof(struct qe_ic));
+       if (qe_ic == NULL)
+               return;
+
+       memset(qe_ic, 0, sizeof(struct qe_ic));
+       qe_ic->of_node = node ? of_node_get(node) : NULL;
+
+       qe_ic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR,
+                                       NR_QE_IC_INTS, &qe_ic_host_ops, 0);
+       if (qe_ic->irqhost == NULL) {
+               of_node_put(node);
+               return;
+       }
+
+       ret = of_address_to_resource(node, 0, &res);
+       if (ret)
+               return;
+
+       qe_ic->regs = ioremap(res.start, res.end - res.start + 1);
+
+       qe_ic->irqhost->host_data = qe_ic;
+       qe_ic->hc_irq = qe_ic_irq_chip;
+
+       qe_ic->virq_high = irq_of_parse_and_map(node, 0);
+       qe_ic->virq_low = irq_of_parse_and_map(node, 1);
+
+       if (qe_ic->virq_low == NO_IRQ) {
+               printk(KERN_ERR "Failed to map QE_IC low IRQ\n");
+               return;
+       }
+
+       /* default priority scheme is grouped. If spread mode is    */
+       /* required, configure cicr accordingly.                    */
+       if (flags & QE_IC_SPREADMODE_GRP_W)
+               temp |= CICR_GWCC;
+       if (flags & QE_IC_SPREADMODE_GRP_X)
+               temp |= CICR_GXCC;
+       if (flags & QE_IC_SPREADMODE_GRP_Y)
+               temp |= CICR_GYCC;
+       if (flags & QE_IC_SPREADMODE_GRP_Z)
+               temp |= CICR_GZCC;
+       if (flags & QE_IC_SPREADMODE_GRP_RISCA)
+               temp |= CICR_GRTA;
+       if (flags & QE_IC_SPREADMODE_GRP_RISCB)
+               temp |= CICR_GRTB;
+
+       /* choose destination signal for highest priority interrupt */
+       if (flags & QE_IC_HIGH_SIGNAL) {
+               temp |= (SIGNAL_HIGH << CICR_HPIT_SHIFT);
+               high_active = 1;
+       }
+
+       qe_ic_write(qe_ic->regs, QEIC_CICR, temp);
+
+       set_irq_data(qe_ic->virq_low, qe_ic);
+       set_irq_chained_handler(qe_ic->virq_low, qe_ic_cascade_low);
+
+       if (qe_ic->virq_high != NO_IRQ) {
+               set_irq_data(qe_ic->virq_high, qe_ic);
+               set_irq_chained_handler(qe_ic->virq_high, qe_ic_cascade_high);
+       }
+
+       printk("QEIC (%d IRQ sources) at %p\n", NR_QE_IC_INTS, qe_ic->regs);
+}
+
+void qe_ic_set_highest_priority(unsigned int virq, int high)
+{
+       struct qe_ic *qe_ic = qe_ic_from_irq(virq);
+       unsigned int src = virq_to_hw(virq);
+       u32 temp = 0;
+
+       temp = qe_ic_read(qe_ic->regs, QEIC_CICR);
+
+       temp &= ~CICR_HP_MASK;
+       temp |= src << CICR_HP_SHIFT;
+
+       temp &= ~CICR_HPIT_MASK;
+       temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << CICR_HPIT_SHIFT;
+
+       qe_ic_write(qe_ic->regs, QEIC_CICR, temp);
+}
+
+/* Set Priority level within its group, from 1 to 8 */
+int qe_ic_set_priority(unsigned int virq, unsigned int priority)
+{
+       struct qe_ic *qe_ic = qe_ic_from_irq(virq);
+       unsigned int src = virq_to_hw(virq);
+       u32 temp;
+
+       if (priority > 8 || priority == 0)
+               return -EINVAL;
+       if (src > 127)
+               return -EINVAL;
+       if (qe_ic_info[src].pri_reg == 0)
+               return -EINVAL;
+
+       temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].pri_reg);
+
+       if (priority < 4) {
+               temp &= ~(0x7 << (32 - priority * 3));
+               temp |= qe_ic_info[src].pri_code << (32 - priority * 3);
+       } else {
+               temp &= ~(0x7 << (24 - priority * 3));
+               temp |= qe_ic_info[src].pri_code << (24 - priority * 3);
+       }
+
+       qe_ic_write(qe_ic->regs, qe_ic_info[src].pri_reg, temp);
+
+       return 0;
+}
+
+/* Set a QE priority to use high irq, only priority 1~2 can use high irq */
+int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high)
+{
+       struct qe_ic *qe_ic = qe_ic_from_irq(virq);
+       unsigned int src = virq_to_hw(virq);
+       u32 temp, control_reg = QEIC_CICNR, shift = 0;
+
+       if (priority > 2 || priority == 0)
+               return -EINVAL;
+
+       switch (qe_ic_info[src].pri_reg) {
+       case QEIC_CIPZCC:
+               shift = CICNR_ZCC1T_SHIFT;
+               break;
+       case QEIC_CIPWCC:
+               shift = CICNR_WCC1T_SHIFT;
+               break;
+       case QEIC_CIPYCC:
+               shift = CICNR_YCC1T_SHIFT;
+               break;
+       case QEIC_CIPXCC:
+               shift = CICNR_XCC1T_SHIFT;
+               break;
+       case QEIC_CIPRTA:
+               shift = CRICR_RTA1T_SHIFT;
+               control_reg = QEIC_CRICR;
+               break;
+       case QEIC_CIPRTB:
+               shift = CRICR_RTB1T_SHIFT;
+               control_reg = QEIC_CRICR;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       shift += (2 - priority) * 2;
+       temp = qe_ic_read(qe_ic->regs, control_reg);
+       temp &= ~(SIGNAL_MASK << shift);
+       temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << shift;
+       qe_ic_write(qe_ic->regs, control_reg, temp);
+
+       return 0;
+}
+
+static struct sysdev_class qe_ic_sysclass = {
+       set_kset_name("qe_ic"),
+};
+
+static struct sys_device device_qe_ic = {
+       .id = 0,
+       .cls = &qe_ic_sysclass,
+};
+
+static int __init init_qe_ic_sysfs(void)
+{
+       int rc;
+
+       printk(KERN_DEBUG "Registering qe_ic with sysfs...\n");
+
+       rc = sysdev_class_register(&qe_ic_sysclass);
+       if (rc) {
+               printk(KERN_ERR "Failed registering qe_ic sys class\n");
+               return -ENODEV;
+       }
+       rc = sysdev_register(&device_qe_ic);
+       if (rc) {
+               printk(KERN_ERR "Failed registering qe_ic sys device\n");
+               return -ENODEV;
+       }
+       return 0;
+}
+
+subsys_initcall(init_qe_ic_sysfs);
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.h b/arch/powerpc/sysdev/qe_lib/qe_ic.h
new file mode 100644 (file)
index 0000000..9a631ad
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * arch/powerpc/sysdev/qe_lib/qe_ic.h
+ *
+ * QUICC ENGINE Interrupt Controller Header
+ *
+ * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
+ *
+ * Author: Li Yang <leoli@freescale.com>
+ * Based on code from Shlomi Gridish <gridish@freescale.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#ifndef _POWERPC_SYSDEV_QE_IC_H
+#define _POWERPC_SYSDEV_QE_IC_H
+
+#include <asm/qe_ic.h>
+
+#define NR_QE_IC_INTS          64
+
+/* QE IC registers offset */
+#define QEIC_CICR              0x00
+#define QEIC_CIVEC             0x04
+#define QEIC_CRIPNR            0x08
+#define QEIC_CIPNR             0x0c
+#define QEIC_CIPXCC            0x10
+#define QEIC_CIPYCC            0x14
+#define QEIC_CIPWCC            0x18
+#define QEIC_CIPZCC            0x1c
+#define QEIC_CIMR              0x20
+#define QEIC_CRIMR             0x24
+#define QEIC_CICNR             0x28
+#define QEIC_CIPRTA            0x30
+#define QEIC_CIPRTB            0x34
+#define QEIC_CRICR             0x3c
+#define QEIC_CHIVEC            0x60
+
+/* Interrupt priority registers */
+#define CIPCC_SHIFT_PRI0       29
+#define CIPCC_SHIFT_PRI1       26
+#define CIPCC_SHIFT_PRI2       23
+#define CIPCC_SHIFT_PRI3       20
+#define CIPCC_SHIFT_PRI4       13
+#define CIPCC_SHIFT_PRI5       10
+#define CIPCC_SHIFT_PRI6       7
+#define CIPCC_SHIFT_PRI7       4
+
+/* CICR priority modes */
+#define CICR_GWCC              0x00040000
+#define CICR_GXCC              0x00020000
+#define CICR_GYCC              0x00010000
+#define CICR_GZCC              0x00080000
+#define CICR_GRTA              0x00200000
+#define CICR_GRTB              0x00400000
+#define CICR_HPIT_SHIFT                8
+#define CICR_HPIT_MASK         0x00000300
+#define CICR_HP_SHIFT          24
+#define CICR_HP_MASK           0x3f000000
+
+/* CICNR */
+#define CICNR_WCC1T_SHIFT      20
+#define CICNR_ZCC1T_SHIFT      28
+#define CICNR_YCC1T_SHIFT      12
+#define CICNR_XCC1T_SHIFT      4
+
+/* CRICR */
+#define CRICR_RTA1T_SHIFT      20
+#define CRICR_RTB1T_SHIFT      28
+
+/* Signal indicator */
+#define SIGNAL_MASK            3
+#define SIGNAL_HIGH            2
+#define SIGNAL_LOW             0
+
+struct qe_ic {
+       /* Control registers offset */
+       volatile u32 __iomem *regs;
+
+       /* The remapper for this QEIC */
+       struct irq_host *irqhost;
+
+       /* The "linux" controller struct */
+       struct irq_chip hc_irq;
+
+       /* The device node of the interrupt controller */
+       struct device_node *of_node;
+
+       /* VIRQ numbers of QE high/low irqs */
+       unsigned int virq_high;
+       unsigned int virq_low;
+};
+
+/*
+ * QE interrupt controller internal structure
+ */
+struct qe_ic_info {
+       u32     mask;     /* location of this source at the QIMR register. */
+       u32     mask_reg; /* Mask register offset */
+       u8      pri_code; /* for grouped interrupts sources - the interrupt
+                            code as appears at the group priority register */
+       u32     pri_reg;  /* Group priority register offset */
+};
+
+#endif /* _POWERPC_SYSDEV_QE_IC_H */
diff --git a/arch/powerpc/sysdev/qe_lib/qe_io.c b/arch/powerpc/sysdev/qe_lib/qe_io.c
new file mode 100644 (file)
index 0000000..aea4359
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * arch/powerpc/sysdev/qe_lib/qe_io.c
+ *
+ * QE Parallel I/O ports configuration routines
+ *
+ * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
+ *
+ * Author: Li Yang <LeoLi@freescale.com>
+ * Based on code from Shlomi Gridish <gridish@freescale.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <sysdev/fsl_soc.h>
+
+#undef DEBUG
+
+#define NUM_OF_PINS    32
+
+struct port_regs {
+       __be32  cpodr;          /* Open drain register */
+       __be32  cpdata;         /* Data register */
+       __be32  cpdir1;         /* Direction register */
+       __be32  cpdir2;         /* Direction register */
+       __be32  cppar1;         /* Pin assignment register */
+       __be32  cppar2;         /* Pin assignment register */
+};
+
+static struct port_regs *par_io = NULL;
+static int num_par_io_ports = 0;
+
+int par_io_init(struct device_node *np)
+{
+       struct resource res;
+       int ret;
+       const u32 *num_ports;
+
+       /* Map Parallel I/O ports registers */
+       ret = of_address_to_resource(np, 0, &res);
+       if (ret)
+               return ret;
+       par_io = ioremap(res.start, res.end - res.start + 1);
+
+       num_ports = get_property(np, "num-ports", NULL);
+       if (num_ports)
+               num_par_io_ports = *num_ports;
+
+       return 0;
+}
+
+int par_io_config_pin(u8 port, u8 pin, int dir, int open_drain,
+                     int assignment, int has_irq)
+{
+       u32 pin_mask1bit, pin_mask2bits, new_mask2bits, tmp_val;
+
+       if (!par_io)
+               return -1;
+
+       /* calculate pin location for single and 2 bits information */
+       pin_mask1bit = (u32) (1 << (NUM_OF_PINS - (pin + 1)));
+
+       /* Set open drain, if required */
+       tmp_val = in_be32(&par_io[port].cpodr);
+       if (open_drain)
+               out_be32(&par_io[port].cpodr, pin_mask1bit | tmp_val);
+       else
+               out_be32(&par_io[port].cpodr, ~pin_mask1bit & tmp_val);
+
+       /* define direction */
+       tmp_val = (pin > (NUM_OF_PINS / 2) - 1) ?
+               in_be32(&par_io[port].cpdir2) :
+               in_be32(&par_io[port].cpdir1);
+
+       /* get all bits mask for 2 bit per port */
+       pin_mask2bits = (u32) (0x3 << (NUM_OF_PINS -
+                               (pin % (NUM_OF_PINS / 2) + 1) * 2));
+
+       /* Get the final mask we need for the right definition */
+       new_mask2bits = (u32) (dir << (NUM_OF_PINS -
+                               (pin % (NUM_OF_PINS / 2) + 1) * 2));
+
+       /* clear and set 2 bits mask */
+       if (pin > (NUM_OF_PINS / 2) - 1) {
+               out_be32(&par_io[port].cpdir2,
+                        ~pin_mask2bits & tmp_val);
+               tmp_val &= ~pin_mask2bits;
+               out_be32(&par_io[port].cpdir2, new_mask2bits | tmp_val);
+       } else {
+               out_be32(&par_io[port].cpdir1,
+                        ~pin_mask2bits & tmp_val);
+               tmp_val &= ~pin_mask2bits;
+               out_be32(&par_io[port].cpdir1, new_mask2bits | tmp_val);
+       }
+       /* define pin assignment */
+       tmp_val = (pin > (NUM_OF_PINS / 2) - 1) ?
+               in_be32(&par_io[port].cppar2) :
+               in_be32(&par_io[port].cppar1);
+
+       new_mask2bits = (u32) (assignment << (NUM_OF_PINS -
+                       (pin % (NUM_OF_PINS / 2) + 1) * 2));
+       /* clear and set 2 bits mask */
+       if (pin > (NUM_OF_PINS / 2) - 1) {
+               out_be32(&par_io[port].cppar2,
+                        ~pin_mask2bits & tmp_val);
+               tmp_val &= ~pin_mask2bits;
+               out_be32(&par_io[port].cppar2, new_mask2bits | tmp_val);
+       } else {
+               out_be32(&par_io[port].cppar1,
+                        ~pin_mask2bits & tmp_val);
+               tmp_val &= ~pin_mask2bits;
+               out_be32(&par_io[port].cppar1, new_mask2bits | tmp_val);
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(par_io_config_pin);
+
+int par_io_data_set(u8 port, u8 pin, u8 val)
+{
+       u32 pin_mask, tmp_val;
+
+       if (port >= num_par_io_ports)
+               return -EINVAL;
+       if (pin >= NUM_OF_PINS)
+               return -EINVAL;
+       /* calculate pin location */
+       pin_mask = (u32) (1 << (NUM_OF_PINS - 1 - pin));
+
+       tmp_val = in_be32(&par_io[port].cpdata);
+
+       if (val == 0)           /* clear */
+               out_be32(&par_io[port].cpdata, ~pin_mask & tmp_val);
+       else                    /* set */
+               out_be32(&par_io[port].cpdata, pin_mask | tmp_val);
+
+       return 0;
+}
+EXPORT_SYMBOL(par_io_data_set);
+
+int par_io_of_config(struct device_node *np)
+{
+       struct device_node *pio;
+       const phandle *ph;
+       int pio_map_len;
+       const unsigned int *pio_map;
+
+       if (par_io == NULL) {
+               printk(KERN_ERR "par_io not initialized \n");
+               return -1;
+       }
+
+       ph = get_property(np, "pio-handle", NULL);
+       if (ph == 0) {
+               printk(KERN_ERR "pio-handle not available \n");
+               return -1;
+       }
+
+       pio = of_find_node_by_phandle(*ph);
+
+       pio_map = get_property(pio, "pio-map", &pio_map_len);
+       if (pio_map == NULL) {
+               printk(KERN_ERR "pio-map is not set! \n");
+               return -1;
+       }
+       pio_map_len /= sizeof(unsigned int);
+       if ((pio_map_len % 6) != 0) {
+               printk(KERN_ERR "pio-map format wrong! \n");
+               return -1;
+       }
+
+       while (pio_map_len > 0) {
+               par_io_config_pin((u8) pio_map[0], (u8) pio_map[1],
+                               (int) pio_map[2], (int) pio_map[3],
+                               (int) pio_map[4], (int) pio_map[5]);
+               pio_map += 6;
+               pio_map_len -= 6;
+       }
+       of_node_put(pio);
+       return 0;
+}
+EXPORT_SYMBOL(par_io_of_config);
+
+#ifdef DEBUG
+static void dump_par_io(void)
+{
+       int i;
+
+       printk(KERN_INFO "PAR IO registars:\n");
+       printk(KERN_INFO "Base address: 0x%08x\n", (u32) par_io);
+       for (i = 0; i < num_par_io_ports; i++) {
+               printk(KERN_INFO "cpodr[%d] : addr - 0x%08x, val - 0x%08x\n",
+                      i, (u32) & par_io[i].cpodr,
+                      in_be32(&par_io[i].cpodr));
+               printk(KERN_INFO "cpdata[%d]: addr - 0x%08x, val - 0x%08x\n",
+                      i, (u32) & par_io[i].cpdata,
+                      in_be32(&par_io[i].cpdata));
+               printk(KERN_INFO "cpdir1[%d]: addr - 0x%08x, val - 0x%08x\n",
+                      i, (u32) & par_io[i].cpdir1,
+                      in_be32(&par_io[i].cpdir1));
+               printk(KERN_INFO "cpdir2[%d]: addr - 0x%08x, val - 0x%08x\n",
+                      i, (u32) & par_io[i].cpdir2,
+                      in_be32(&par_io[i].cpdir2));
+               printk(KERN_INFO "cppar1[%d]: addr - 0x%08x, val - 0x%08x\n",
+                      i, (u32) & par_io[i].cppar1,
+                      in_be32(&par_io[i].cppar1));
+               printk(KERN_INFO "cppar2[%d]: addr - 0x%08x, val - 0x%08x\n",
+                      i, (u32) & par_io[i].cppar2,
+                      in_be32(&par_io[i].cppar2));
+       }
+
+}
+EXPORT_SYMBOL(dump_par_io);
+#endif /* DEBUG */
diff --git a/arch/powerpc/sysdev/qe_lib/ucc.c b/arch/powerpc/sysdev/qe_lib/ucc.c
new file mode 100644 (file)
index 0000000..916c9e5
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * arch/powerpc/sysdev/qe_lib/ucc.c
+ *
+ * QE UCC API Set - UCC specific routines implementations.
+ *
+ * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
+ *
+ * Authors:    Shlomi Gridish <gridish@freescale.com>
+ *             Li Yang <leoli@freescale.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/stddef.h>
+
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/immap_qe.h>
+#include <asm/qe.h>
+#include <asm/ucc.h>
+
+static DEFINE_SPINLOCK(ucc_lock);
+
+int ucc_set_qe_mux_mii_mng(int ucc_num)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&ucc_lock, flags);
+       out_be32(&qe_immr->qmx.cmxgcr,
+                ((in_be32(&qe_immr->qmx.cmxgcr) &
+                  ~QE_CMXGCR_MII_ENET_MNG) |
+                 (ucc_num << QE_CMXGCR_MII_ENET_MNG_SHIFT)));
+       spin_unlock_irqrestore(&ucc_lock, flags);
+
+       return 0;
+}
+
+int ucc_set_type(int ucc_num, struct ucc_common *regs,
+                enum ucc_speed_type speed)
+{
+       u8 guemr = 0;
+
+       /* check if the UCC number is in range. */
+       if ((ucc_num > UCC_MAX_NUM - 1) || (ucc_num < 0))
+               return -EINVAL;
+
+       guemr = regs->guemr;
+       guemr &= ~(UCC_GUEMR_MODE_MASK_RX | UCC_GUEMR_MODE_MASK_TX);
+       switch (speed) {
+       case UCC_SPEED_TYPE_SLOW:
+               guemr |= (UCC_GUEMR_MODE_SLOW_RX | UCC_GUEMR_MODE_SLOW_TX);
+               break;
+       case UCC_SPEED_TYPE_FAST:
+               guemr |= (UCC_GUEMR_MODE_FAST_RX | UCC_GUEMR_MODE_FAST_TX);
+               break;
+       default:
+               return -EINVAL;
+       }
+       regs->guemr = guemr;
+
+       return 0;
+}
+
+int ucc_init_guemr(struct ucc_common *regs)
+{
+       u8 guemr = 0;
+
+       if (!regs)
+               return -EINVAL;
+
+       /* Set bit 3 (which is reserved in the GUEMR register) to 1 */
+       guemr = UCC_GUEMR_SET_RESERVED3;
+
+       regs->guemr = guemr;
+
+       return 0;
+}
+
+static void get_cmxucr_reg(int ucc_num, volatile u32 ** p_cmxucr, u8 * reg_num,
+                          u8 * shift)
+{
+       switch (ucc_num) {
+       case 0: *p_cmxucr = &(qe_immr->qmx.cmxucr1);
+               *reg_num = 1;
+               *shift = 16;
+               break;
+       case 2: *p_cmxucr = &(qe_immr->qmx.cmxucr1);
+               *reg_num = 1;
+               *shift = 0;
+               break;
+       case 4: *p_cmxucr = &(qe_immr->qmx.cmxucr2);
+               *reg_num = 2;
+               *shift = 16;
+               break;
+       case 6: *p_cmxucr = &(qe_immr->qmx.cmxucr2);
+               *reg_num = 2;
+               *shift = 0;
+               break;
+       case 1: *p_cmxucr = &(qe_immr->qmx.cmxucr3);
+               *reg_num = 3;
+               *shift = 16;
+               break;
+       case 3: *p_cmxucr = &(qe_immr->qmx.cmxucr3);
+               *reg_num = 3;
+               *shift = 0;
+               break;
+       case 5: *p_cmxucr = &(qe_immr->qmx.cmxucr4);
+               *reg_num = 4;
+               *shift = 16;
+               break;
+       case 7: *p_cmxucr = &(qe_immr->qmx.cmxucr4);
+               *reg_num = 4;
+               *shift = 0;
+               break;
+       default:
+               break;
+       }
+}
+
+int ucc_mux_set_grant_tsa_bkpt(int ucc_num, int set, u32 mask)
+{
+       volatile u32 *p_cmxucr;
+       u8 reg_num;
+       u8 shift;
+
+       /* check if the UCC number is in range. */
+       if ((ucc_num > UCC_MAX_NUM - 1) || (ucc_num < 0))
+               return -EINVAL;
+
+       get_cmxucr_reg(ucc_num, &p_cmxucr, &reg_num, &shift);
+
+       if (set)
+               out_be32(p_cmxucr, in_be32(p_cmxucr) | (mask << shift));
+       else
+               out_be32(p_cmxucr, in_be32(p_cmxucr) & ~(mask << shift));
+
+       return 0;
+}
+
+int ucc_set_qe_mux_rxtx(int ucc_num, enum qe_clock clock, enum comm_dir mode)
+{
+       volatile u32 *p_cmxucr;
+       u8 reg_num;
+       u8 shift;
+       u32 clock_bits;
+       u32 clock_mask;
+       int source = -1;
+
+       /* check if the UCC number is in range. */
+       if ((ucc_num > UCC_MAX_NUM - 1) || (ucc_num < 0))
+               return -EINVAL;
+
+       if (!((mode == COMM_DIR_RX) || (mode == COMM_DIR_TX))) {
+               printk(KERN_ERR
+                      "ucc_set_qe_mux_rxtx: bad comm mode type passed.");
+               return -EINVAL;
+       }
+
+       get_cmxucr_reg(ucc_num, &p_cmxucr, &reg_num, &shift);
+
+       switch (reg_num) {
+       case 1:
+               switch (clock) {
+               case QE_BRG1:   source = 1; break;
+               case QE_BRG2:   source = 2; break;
+               case QE_BRG7:   source = 3; break;
+               case QE_BRG8:   source = 4; break;
+               case QE_CLK9:   source = 5; break;
+               case QE_CLK10:  source = 6; break;
+               case QE_CLK11:  source = 7; break;
+               case QE_CLK12:  source = 8; break;
+               case QE_CLK15:  source = 9; break;
+               case QE_CLK16:  source = 10; break;
+               default:        source = -1; break;
+               }
+               break;
+       case 2:
+               switch (clock) {
+               case QE_BRG5:   source = 1; break;
+               case QE_BRG6:   source = 2; break;
+               case QE_BRG7:   source = 3; break;
+               case QE_BRG8:   source = 4; break;
+               case QE_CLK13:  source = 5; break;
+               case QE_CLK14:  source = 6; break;
+               case QE_CLK19:  source = 7; break;
+               case QE_CLK20:  source = 8; break;
+               case QE_CLK15:  source = 9; break;
+               case QE_CLK16:  source = 10; break;
+               default:        source = -1; break;
+               }
+               break;
+       case 3:
+               switch (clock) {
+               case QE_BRG9:   source = 1; break;
+               case QE_BRG10:  source = 2; break;
+               case QE_BRG15:  source = 3; break;
+               case QE_BRG16:  source = 4; break;
+               case QE_CLK3:   source = 5; break;
+               case QE_CLK4:   source = 6; break;
+               case QE_CLK17:  source = 7; break;
+               case QE_CLK18:  source = 8; break;
+               case QE_CLK7:   source = 9; break;
+               case QE_CLK8:   source = 10; break;
+               default:        source = -1; break;
+               }
+               break;
+       case 4:
+               switch (clock) {
+               case QE_BRG13:  source = 1; break;
+               case QE_BRG14:  source = 2; break;
+               case QE_BRG15:  source = 3; break;
+               case QE_BRG16:  source = 4; break;
+               case QE_CLK5:   source = 5; break;
+               case QE_CLK6:   source = 6; break;
+               case QE_CLK21:  source = 7; break;
+               case QE_CLK22:  source = 8; break;
+               case QE_CLK7:   source = 9; break;
+               case QE_CLK8:   source = 10; break;
+               default:        source = -1; break;
+               }
+               break;
+       default:
+               source = -1;
+               break;
+       }
+
+       if (source == -1) {
+               printk(KERN_ERR
+                    "ucc_set_qe_mux_rxtx: Bad combination of clock and UCC.");
+               return -ENOENT;
+       }
+
+       clock_bits = (u32) source;
+       clock_mask = QE_CMXUCR_TX_CLK_SRC_MASK;
+       if (mode == COMM_DIR_RX) {
+               clock_bits <<= 4;  /* Rx field is 4 bits to left of Tx field */
+               clock_mask <<= 4;  /* Rx field is 4 bits to left of Tx field */
+       }
+       clock_bits <<= shift;
+       clock_mask <<= shift;
+
+       out_be32(p_cmxucr, (in_be32(p_cmxucr) & ~clock_mask) | clock_bits);
+
+       return 0;
+}
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_fast.c b/arch/powerpc/sysdev/qe_lib/ucc_fast.c
new file mode 100644 (file)
index 0000000..c2be734
--- /dev/null
@@ -0,0 +1,396 @@
+/*
+ * arch/powerpc/sysdev/qe_lib/ucc_fast.c
+ *
+ * QE UCC Fast API Set - UCC Fast specific routines implementations.
+ *
+ * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
+ *
+ * Authors:    Shlomi Gridish <gridish@freescale.com>
+ *             Li Yang <leoli@freescale.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/stddef.h>
+#include <linux/interrupt.h>
+
+#include <asm/io.h>
+#include <asm/immap_qe.h>
+#include <asm/qe.h>
+
+#include <asm/ucc.h>
+#include <asm/ucc_fast.h>
+
+#define uccf_printk(level, format, arg...) \
+       printk(level format "\n", ## arg)
+
+#define uccf_dbg(format, arg...) \
+       uccf_printk(KERN_DEBUG , format , ## arg)
+#define uccf_err(format, arg...) \
+       uccf_printk(KERN_ERR , format , ## arg)
+#define uccf_info(format, arg...) \
+       uccf_printk(KERN_INFO , format , ## arg)
+#define uccf_warn(format, arg...) \
+       uccf_printk(KERN_WARNING , format , ## arg)
+
+#ifdef UCCF_VERBOSE_DEBUG
+#define uccf_vdbg uccf_dbg
+#else
+#define uccf_vdbg(fmt, args...) do { } while (0)
+#endif                         /* UCCF_VERBOSE_DEBUG */
+
+void ucc_fast_dump_regs(struct ucc_fast_private * uccf)
+{
+       uccf_info("UCC%d Fast registers:", uccf->uf_info->ucc_num);
+       uccf_info("Base address: 0x%08x", (u32) uccf->uf_regs);
+
+       uccf_info("gumr  : addr - 0x%08x, val - 0x%08x",
+                 (u32) & uccf->uf_regs->gumr, in_be32(&uccf->uf_regs->gumr));
+       uccf_info("upsmr : addr - 0x%08x, val - 0x%08x",
+                 (u32) & uccf->uf_regs->upsmr, in_be32(&uccf->uf_regs->upsmr));
+       uccf_info("utodr : addr - 0x%08x, val - 0x%04x",
+                 (u32) & uccf->uf_regs->utodr, in_be16(&uccf->uf_regs->utodr));
+       uccf_info("udsr  : addr - 0x%08x, val - 0x%04x",
+                 (u32) & uccf->uf_regs->udsr, in_be16(&uccf->uf_regs->udsr));
+       uccf_info("ucce  : addr - 0x%08x, val - 0x%08x",
+                 (u32) & uccf->uf_regs->ucce, in_be32(&uccf->uf_regs->ucce));
+       uccf_info("uccm  : addr - 0x%08x, val - 0x%08x",
+                 (u32) & uccf->uf_regs->uccm, in_be32(&uccf->uf_regs->uccm));
+       uccf_info("uccs  : addr - 0x%08x, val - 0x%02x",
+                 (u32) & uccf->uf_regs->uccs, uccf->uf_regs->uccs);
+       uccf_info("urfb  : addr - 0x%08x, val - 0x%08x",
+                 (u32) & uccf->uf_regs->urfb, in_be32(&uccf->uf_regs->urfb));
+       uccf_info("urfs  : addr - 0x%08x, val - 0x%04x",
+                 (u32) & uccf->uf_regs->urfs, in_be16(&uccf->uf_regs->urfs));
+       uccf_info("urfet : addr - 0x%08x, val - 0x%04x",
+                 (u32) & uccf->uf_regs->urfet, in_be16(&uccf->uf_regs->urfet));
+       uccf_info("urfset: addr - 0x%08x, val - 0x%04x",
+                 (u32) & uccf->uf_regs->urfset,
+                 in_be16(&uccf->uf_regs->urfset));
+       uccf_info("utfb  : addr - 0x%08x, val - 0x%08x",
+                 (u32) & uccf->uf_regs->utfb, in_be32(&uccf->uf_regs->utfb));
+       uccf_info("utfs  : addr - 0x%08x, val - 0x%04x",
+                 (u32) & uccf->uf_regs->utfs, in_be16(&uccf->uf_regs->utfs));
+       uccf_info("utfet : addr - 0x%08x, val - 0x%04x",
+                 (u32) & uccf->uf_regs->utfet, in_be16(&uccf->uf_regs->utfet));
+       uccf_info("utftt : addr - 0x%08x, val - 0x%04x",
+                 (u32) & uccf->uf_regs->utftt, in_be16(&uccf->uf_regs->utftt));
+       uccf_info("utpt  : addr - 0x%08x, val - 0x%04x",
+                 (u32) & uccf->uf_regs->utpt, in_be16(&uccf->uf_regs->utpt));
+       uccf_info("urtry : addr - 0x%08x, val - 0x%08x",
+                 (u32) & uccf->uf_regs->urtry, in_be32(&uccf->uf_regs->urtry));
+       uccf_info("guemr : addr - 0x%08x, val - 0x%02x",
+                 (u32) & uccf->uf_regs->guemr, uccf->uf_regs->guemr);
+}
+
+u32 ucc_fast_get_qe_cr_subblock(int uccf_num)
+{
+       switch (uccf_num) {
+       case 0: return QE_CR_SUBBLOCK_UCCFAST1;
+       case 1: return QE_CR_SUBBLOCK_UCCFAST2;
+       case 2: return QE_CR_SUBBLOCK_UCCFAST3;
+       case 3: return QE_CR_SUBBLOCK_UCCFAST4;
+       case 4: return QE_CR_SUBBLOCK_UCCFAST5;
+       case 5: return QE_CR_SUBBLOCK_UCCFAST6;
+       case 6: return QE_CR_SUBBLOCK_UCCFAST7;
+       case 7: return QE_CR_SUBBLOCK_UCCFAST8;
+       default: return QE_CR_SUBBLOCK_INVALID;
+       }
+}
+
+void ucc_fast_transmit_on_demand(struct ucc_fast_private * uccf)
+{
+       out_be16(&uccf->uf_regs->utodr, UCC_FAST_TOD);
+}
+
+void ucc_fast_enable(struct ucc_fast_private * uccf, enum comm_dir mode)
+{
+       struct ucc_fast *uf_regs;
+       u32 gumr;
+
+       uf_regs = uccf->uf_regs;
+
+       /* Enable reception and/or transmission on this UCC. */
+       gumr = in_be32(&uf_regs->gumr);
+       if (mode & COMM_DIR_TX) {
+               gumr |= UCC_FAST_GUMR_ENT;
+               uccf->enabled_tx = 1;
+       }
+       if (mode & COMM_DIR_RX) {
+               gumr |= UCC_FAST_GUMR_ENR;
+               uccf->enabled_rx = 1;
+       }
+       out_be32(&uf_regs->gumr, gumr);
+}
+
+void ucc_fast_disable(struct ucc_fast_private * uccf, enum comm_dir mode)
+{
+       struct ucc_fast *uf_regs;
+       u32 gumr;
+
+       uf_regs = uccf->uf_regs;
+
+       /* Disable reception and/or transmission on this UCC. */
+       gumr = in_be32(&uf_regs->gumr);
+       if (mode & COMM_DIR_TX) {
+               gumr &= ~UCC_FAST_GUMR_ENT;
+               uccf->enabled_tx = 0;
+       }
+       if (mode & COMM_DIR_RX) {
+               gumr &= ~UCC_FAST_GUMR_ENR;
+               uccf->enabled_rx = 0;
+       }
+       out_be32(&uf_regs->gumr, gumr);
+}
+
+int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** uccf_ret)
+{
+       struct ucc_fast_private *uccf;
+       struct ucc_fast *uf_regs;
+       u32 gumr = 0;
+       int ret;
+
+       uccf_vdbg("%s: IN", __FUNCTION__);
+
+       if (!uf_info)
+               return -EINVAL;
+
+       /* check if the UCC port number is in range. */
+       if ((uf_info->ucc_num < 0) || (uf_info->ucc_num > UCC_MAX_NUM - 1)) {
+               uccf_err("ucc_fast_init: Illagal UCC number!");
+               return -EINVAL;
+       }
+
+       /* Check that 'max_rx_buf_length' is properly aligned (4). */
+       if (uf_info->max_rx_buf_length & (UCC_FAST_MRBLR_ALIGNMENT - 1)) {
+               uccf_err("ucc_fast_init: max_rx_buf_length not aligned.");
+               return -EINVAL;
+       }
+
+       /* Validate Virtual Fifo register values */
+       if (uf_info->urfs < UCC_FAST_URFS_MIN_VAL) {
+               uccf_err
+                   ("ucc_fast_init: Virtual Fifo register urfs too small.");
+               return -EINVAL;
+       }
+
+       if (uf_info->urfs & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
+               uccf_err
+                   ("ucc_fast_init: Virtual Fifo register urfs not aligned.");
+               return -EINVAL;
+       }
+
+       if (uf_info->urfet & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
+               uccf_err
+                   ("ucc_fast_init: Virtual Fifo register urfet not aligned.");
+               return -EINVAL;
+       }
+
+       if (uf_info->urfset & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
+               uccf_err
+                  ("ucc_fast_init: Virtual Fifo register urfset not aligned.");
+               return -EINVAL;
+       }
+
+       if (uf_info->utfs & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
+               uccf_err
+                   ("ucc_fast_init: Virtual Fifo register utfs not aligned.");
+               return -EINVAL;
+       }
+
+       if (uf_info->utfet & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
+               uccf_err
+                   ("ucc_fast_init: Virtual Fifo register utfet not aligned.");
+               return -EINVAL;
+       }
+
+       if (uf_info->utftt & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
+               uccf_err
+                   ("ucc_fast_init: Virtual Fifo register utftt not aligned.");
+               return -EINVAL;
+       }
+
+       uccf = (struct ucc_fast_private *)
+                kmalloc(sizeof(struct ucc_fast_private), GFP_KERNEL);
+       if (!uccf) {
+               uccf_err
+                   ("ucc_fast_init: No memory for UCC slow data structure!");
+               return -ENOMEM;
+       }
+       memset(uccf, 0, sizeof(struct ucc_fast_private));
+
+       /* Fill fast UCC structure */
+       uccf->uf_info = uf_info;
+       /* Set the PHY base address */
+       uccf->uf_regs =
+           (struct ucc_fast *) ioremap(uf_info->regs, sizeof(struct ucc_fast));
+       if (uccf->uf_regs == NULL) {
+               uccf_err
+                   ("ucc_fast_init: No memory map for UCC slow controller!");
+               return -ENOMEM;
+       }
+
+       uccf->enabled_tx = 0;
+       uccf->enabled_rx = 0;
+       uccf->stopped_tx = 0;
+       uccf->stopped_rx = 0;
+       uf_regs = uccf->uf_regs;
+       uccf->p_ucce = (u32 *) & (uf_regs->ucce);
+       uccf->p_uccm = (u32 *) & (uf_regs->uccm);
+#ifdef STATISTICS
+       uccf->tx_frames = 0;
+       uccf->rx_frames = 0;
+       uccf->rx_discarded = 0;
+#endif                         /* STATISTICS */
+
+       /* Init Guemr register */
+       if ((ret = ucc_init_guemr((struct ucc_common *) (uf_regs)))) {
+               uccf_err("ucc_fast_init: Could not init the guemr register.");
+               ucc_fast_free(uccf);
+               return ret;
+       }
+
+       /* Set UCC to fast type */
+       if ((ret = ucc_set_type(uf_info->ucc_num,
+                               (struct ucc_common *) (uf_regs),
+                               UCC_SPEED_TYPE_FAST))) {
+               uccf_err("ucc_fast_init: Could not set type to fast.");
+               ucc_fast_free(uccf);
+               return ret;
+       }
+
+       uccf->mrblr = uf_info->max_rx_buf_length;
+
+       /* Set GUMR */
+       /* For more details see the hardware spec. */
+       /* gumr starts as zero. */
+       if (uf_info->tci)
+               gumr |= UCC_FAST_GUMR_TCI;
+       gumr |= uf_info->ttx_trx;
+       if (uf_info->cdp)
+               gumr |= UCC_FAST_GUMR_CDP;
+       if (uf_info->ctsp)
+               gumr |= UCC_FAST_GUMR_CTSP;
+       if (uf_info->cds)
+               gumr |= UCC_FAST_GUMR_CDS;
+       if (uf_info->ctss)
+               gumr |= UCC_FAST_GUMR_CTSS;
+       if (uf_info->txsy)
+               gumr |= UCC_FAST_GUMR_TXSY;
+       if (uf_info->rsyn)
+               gumr |= UCC_FAST_GUMR_RSYN;
+       gumr |= uf_info->synl;
+       if (uf_info->rtsm)
+               gumr |= UCC_FAST_GUMR_RTSM;
+       gumr |= uf_info->renc;
+       if (uf_info->revd)
+               gumr |= UCC_FAST_GUMR_REVD;
+       gumr |= uf_info->tenc;
+       gumr |= uf_info->tcrc;
+       gumr |= uf_info->mode;
+       out_be32(&uf_regs->gumr, gumr);
+
+       /* Allocate memory for Tx Virtual Fifo */
+       uccf->ucc_fast_tx_virtual_fifo_base_offset =
+           qe_muram_alloc(uf_info->utfs, UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
+       if (IS_MURAM_ERR(uccf->ucc_fast_tx_virtual_fifo_base_offset)) {
+               uccf_err
+                   ("ucc_fast_init: Can not allocate MURAM memory for "
+                       "struct ucc_fastx_virtual_fifo_base_offset.");
+               uccf->ucc_fast_tx_virtual_fifo_base_offset = 0;
+               ucc_fast_free(uccf);
+               return -ENOMEM;
+       }
+
+       /* Allocate memory for Rx Virtual Fifo */
+       uccf->ucc_fast_rx_virtual_fifo_base_offset =
+           qe_muram_alloc(uf_info->urfs +
+                          (u32)
+                          UCC_FAST_RECEIVE_VIRTUAL_FIFO_SIZE_FUDGE_FACTOR,
+                          UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
+       if (IS_MURAM_ERR(uccf->ucc_fast_rx_virtual_fifo_base_offset)) {
+               uccf_err
+                   ("ucc_fast_init: Can not allocate MURAM memory for "
+                       "ucc_fast_rx_virtual_fifo_base_offset.");
+               uccf->ucc_fast_rx_virtual_fifo_base_offset = 0;
+               ucc_fast_free(uccf);
+               return -ENOMEM;
+       }
+
+       /* Set Virtual Fifo registers */
+       out_be16(&uf_regs->urfs, uf_info->urfs);
+       out_be16(&uf_regs->urfet, uf_info->urfet);
+       out_be16(&uf_regs->urfset, uf_info->urfset);
+       out_be16(&uf_regs->utfs, uf_info->utfs);
+       out_be16(&uf_regs->utfet, uf_info->utfet);
+       out_be16(&uf_regs->utftt, uf_info->utftt);
+       /* utfb, urfb are offsets from MURAM base */
+       out_be32(&uf_regs->utfb, uccf->ucc_fast_tx_virtual_fifo_base_offset);
+       out_be32(&uf_regs->urfb, uccf->ucc_fast_rx_virtual_fifo_base_offset);
+
+       /* Mux clocking */
+       /* Grant Support */
+       ucc_set_qe_mux_grant(uf_info->ucc_num, uf_info->grant_support);
+       /* Breakpoint Support */
+       ucc_set_qe_mux_bkpt(uf_info->ucc_num, uf_info->brkpt_support);
+       /* Set Tsa or NMSI mode. */
+       ucc_set_qe_mux_tsa(uf_info->ucc_num, uf_info->tsa);
+       /* If NMSI (not Tsa), set Tx and Rx clock. */
+       if (!uf_info->tsa) {
+               /* Rx clock routing */
+               if (uf_info->rx_clock != QE_CLK_NONE) {
+                       if (ucc_set_qe_mux_rxtx
+                           (uf_info->ucc_num, uf_info->rx_clock,
+                            COMM_DIR_RX)) {
+                               uccf_err
+               ("ucc_fast_init: Illegal value for parameter 'RxClock'.");
+                               ucc_fast_free(uccf);
+                               return -EINVAL;
+                       }
+               }
+               /* Tx clock routing */
+               if (uf_info->tx_clock != QE_CLK_NONE) {
+                       if (ucc_set_qe_mux_rxtx
+                           (uf_info->ucc_num, uf_info->tx_clock,
+                            COMM_DIR_TX)) {
+                               uccf_err
+               ("ucc_fast_init: Illegal value for parameter 'TxClock'.");
+                               ucc_fast_free(uccf);
+                               return -EINVAL;
+                       }
+               }
+       }
+
+       /* Set interrupt mask register at UCC level. */
+       out_be32(&uf_regs->uccm, uf_info->uccm_mask);
+
+       /* First, clear anything pending at UCC level,
+        * otherwise, old garbage may come through
+        * as soon as the dam is opened
+        * Writing '1' clears
+        */
+       out_be32(&uf_regs->ucce, 0xffffffff);
+
+       *uccf_ret = uccf;
+       return 0;
+}
+
+void ucc_fast_free(struct ucc_fast_private * uccf)
+{
+       if (!uccf)
+               return;
+
+       if (uccf->ucc_fast_tx_virtual_fifo_base_offset)
+               qe_muram_free(uccf->ucc_fast_tx_virtual_fifo_base_offset);
+
+       if (uccf->ucc_fast_rx_virtual_fifo_base_offset)
+               qe_muram_free(uccf->ucc_fast_rx_virtual_fifo_base_offset);
+
+       kfree(uccf);
+}
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_slow.c b/arch/powerpc/sysdev/qe_lib/ucc_slow.c
new file mode 100644 (file)
index 0000000..1fb88ef
--- /dev/null
@@ -0,0 +1,404 @@
+/*
+ * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
+ *
+ * Authors:    Shlomi Gridish <gridish@freescale.com>
+ *             Li Yang <leoli@freescale.com>
+ *
+ * Description:
+ * QE UCC Slow API Set - UCC Slow specific routines implementations.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/stddef.h>
+#include <linux/interrupt.h>
+
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/immap_qe.h>
+#include <asm/qe.h>
+
+#include <asm/ucc.h>
+#include <asm/ucc_slow.h>
+
+#define uccs_printk(level, format, arg...) \
+        printk(level format "\n", ## arg)
+
+#define uccs_dbg(format, arg...) \
+       uccs_printk(KERN_DEBUG , format , ## arg)
+#define uccs_err(format, arg...) \
+       uccs_printk(KERN_ERR , format , ## arg)
+#define uccs_info(format, arg...) \
+       uccs_printk(KERN_INFO , format , ## arg)
+#define uccs_warn(format, arg...) \
+       uccs_printk(KERN_WARNING , format , ## arg)
+
+#ifdef UCCS_VERBOSE_DEBUG
+#define uccs_vdbg uccs_dbg
+#else
+#define uccs_vdbg(fmt, args...) do { } while (0)
+#endif                         /* UCCS_VERBOSE_DEBUG */
+
+u32 ucc_slow_get_qe_cr_subblock(int uccs_num)
+{
+       switch (uccs_num) {
+       case 0: return QE_CR_SUBBLOCK_UCCSLOW1;
+       case 1: return QE_CR_SUBBLOCK_UCCSLOW2;
+       case 2: return QE_CR_SUBBLOCK_UCCSLOW3;
+       case 3: return QE_CR_SUBBLOCK_UCCSLOW4;
+       case 4: return QE_CR_SUBBLOCK_UCCSLOW5;
+       case 5: return QE_CR_SUBBLOCK_UCCSLOW6;
+       case 6: return QE_CR_SUBBLOCK_UCCSLOW7;
+       case 7: return QE_CR_SUBBLOCK_UCCSLOW8;
+       default: return QE_CR_SUBBLOCK_INVALID;
+       }
+}
+
+void ucc_slow_poll_transmitter_now(struct ucc_slow_private * uccs)
+{
+       out_be16(&uccs->us_regs->utodr, UCC_SLOW_TOD);
+}
+
+void ucc_slow_graceful_stop_tx(struct ucc_slow_private * uccs)
+{
+       struct ucc_slow_info *us_info = uccs->us_info;
+       u32 id;
+
+       id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
+       qe_issue_cmd(QE_GRACEFUL_STOP_TX, id,
+                        QE_CR_PROTOCOL_UNSPECIFIED, 0);
+}
+
+void ucc_slow_stop_tx(struct ucc_slow_private * uccs)
+{
+       struct ucc_slow_info *us_info = uccs->us_info;
+       u32 id;
+
+       id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
+       qe_issue_cmd(QE_STOP_TX, id, QE_CR_PROTOCOL_UNSPECIFIED, 0);
+}
+
+void ucc_slow_restart_tx(struct ucc_slow_private * uccs)
+{
+       struct ucc_slow_info *us_info = uccs->us_info;
+       u32 id;
+
+       id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
+       qe_issue_cmd(QE_RESTART_TX, id, QE_CR_PROTOCOL_UNSPECIFIED, 0);
+}
+
+void ucc_slow_enable(struct ucc_slow_private * uccs, enum comm_dir mode)
+{
+       struct ucc_slow *us_regs;
+       u32 gumr_l;
+
+       us_regs = uccs->us_regs;
+
+       /* Enable reception and/or transmission on this UCC. */
+       gumr_l = in_be32(&us_regs->gumr_l);
+       if (mode & COMM_DIR_TX) {
+               gumr_l |= UCC_SLOW_GUMR_L_ENT;
+               uccs->enabled_tx = 1;
+       }
+       if (mode & COMM_DIR_RX) {
+               gumr_l |= UCC_SLOW_GUMR_L_ENR;
+               uccs->enabled_rx = 1;
+       }
+       out_be32(&us_regs->gumr_l, gumr_l);
+}
+
+void ucc_slow_disable(struct ucc_slow_private * uccs, enum comm_dir mode)
+{
+       struct ucc_slow *us_regs;
+       u32 gumr_l;
+
+       us_regs = uccs->us_regs;
+
+       /* Disable reception and/or transmission on this UCC. */
+       gumr_l = in_be32(&us_regs->gumr_l);
+       if (mode & COMM_DIR_TX) {
+               gumr_l &= ~UCC_SLOW_GUMR_L_ENT;
+               uccs->enabled_tx = 0;
+       }
+       if (mode & COMM_DIR_RX) {
+               gumr_l &= ~UCC_SLOW_GUMR_L_ENR;
+               uccs->enabled_rx = 0;
+       }
+       out_be32(&us_regs->gumr_l, gumr_l);
+}
+
+int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** uccs_ret)
+{
+       u32 i;
+       struct ucc_slow *us_regs;
+       u32 gumr;
+       u8 function_code = 0;
+       u8 *bd;
+       struct ucc_slow_private *uccs;
+       u32 id;
+       u32 command;
+       int ret;
+
+       uccs_vdbg("%s: IN", __FUNCTION__);
+
+       if (!us_info)
+               return -EINVAL;
+
+       /* check if the UCC port number is in range. */
+       if ((us_info->ucc_num < 0) || (us_info->ucc_num > UCC_MAX_NUM - 1)) {
+               uccs_err("ucc_slow_init: Illagal UCC number!");
+               return -EINVAL;
+       }
+
+       /*
+        * Set mrblr
+        * Check that 'max_rx_buf_length' is properly aligned (4), unless
+        * rfw is 1, meaning that QE accepts one byte at a time, unlike normal
+        * case when QE accepts 32 bits at a time.
+        */
+       if ((!us_info->rfw) &&
+               (us_info->max_rx_buf_length & (UCC_SLOW_MRBLR_ALIGNMENT - 1))) {
+               uccs_err("max_rx_buf_length not aligned.");
+               return -EINVAL;
+       }
+
+       uccs = (struct ucc_slow_private *)
+               kmalloc(sizeof(struct ucc_slow_private), GFP_KERNEL);
+       if (!uccs) {
+               uccs_err
+                   ("ucc_slow_init: No memory for UCC slow data structure!");
+               return -ENOMEM;
+       }
+       memset(uccs, 0, sizeof(struct ucc_slow_private));
+
+       /* Fill slow UCC structure */
+       uccs->us_info = us_info;
+       uccs->saved_uccm = 0;
+       uccs->p_rx_frame = 0;
+       uccs->us_regs = us_info->us_regs;
+       us_regs = uccs->us_regs;
+       uccs->p_ucce = (u16 *) & (us_regs->ucce);
+       uccs->p_uccm = (u16 *) & (us_regs->uccm);
+#ifdef STATISTICS
+       uccs->rx_frames = 0;
+       uccs->tx_frames = 0;
+       uccs->rx_discarded = 0;
+#endif                         /* STATISTICS */
+
+       /* Get PRAM base */
+       uccs->us_pram_offset = qe_muram_alloc(UCC_SLOW_PRAM_SIZE,
+                                                ALIGNMENT_OF_UCC_SLOW_PRAM);
+       if (IS_MURAM_ERR(uccs->us_pram_offset)) {
+               uccs_err
+                   ("ucc_slow_init: Can not allocate MURAM memory "
+                       "for Slow UCC.");
+               ucc_slow_free(uccs);
+               return -ENOMEM;
+       }
+       id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
+       qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, id, QE_CR_PROTOCOL_UNSPECIFIED,
+                       (u32) uccs->us_pram_offset);
+
+       uccs->us_pram = qe_muram_addr(uccs->us_pram_offset);
+
+       /* Init Guemr register */
+       if ((ret = ucc_init_guemr((struct ucc_common *) (us_info->us_regs)))) {
+               uccs_err("ucc_slow_init: Could not init the guemr register.");
+               ucc_slow_free(uccs);
+               return ret;
+       }
+
+       /* Set UCC to slow type */
+       if ((ret = ucc_set_type(us_info->ucc_num,
+                               (struct ucc_common *) (us_info->us_regs),
+                               UCC_SPEED_TYPE_SLOW))) {
+               uccs_err("ucc_slow_init: Could not init the guemr register.");
+               ucc_slow_free(uccs);
+               return ret;
+       }
+
+       out_be16(&uccs->us_pram->mrblr, us_info->max_rx_buf_length);
+
+       INIT_LIST_HEAD(&uccs->confQ);
+
+       /* Allocate BDs. */
+       uccs->rx_base_offset =
+               qe_muram_alloc(us_info->rx_bd_ring_len * sizeof(struct qe_bd),
+                               QE_ALIGNMENT_OF_BD);
+       if (IS_MURAM_ERR(uccs->rx_base_offset)) {
+               uccs_err("ucc_slow_init: No memory for Rx BD's.");
+               uccs->rx_base_offset = 0;
+               ucc_slow_free(uccs);
+               return -ENOMEM;
+       }
+
+       uccs->tx_base_offset =
+               qe_muram_alloc(us_info->tx_bd_ring_len * sizeof(struct qe_bd),
+                       QE_ALIGNMENT_OF_BD);
+       if (IS_MURAM_ERR(uccs->tx_base_offset)) {
+               uccs_err("ucc_slow_init: No memory for Tx BD's.");
+               uccs->tx_base_offset = 0;
+               ucc_slow_free(uccs);
+               return -ENOMEM;
+       }
+
+       /* Init Tx bds */
+       bd = uccs->confBd = uccs->tx_bd = qe_muram_addr(uccs->tx_base_offset);
+       for (i = 0; i < us_info->tx_bd_ring_len; i++) {
+               /* clear bd buffer */
+               out_be32(&(((struct qe_bd *)bd)->buf), 0);
+               /* set bd status and length */
+               out_be32((u32*)bd, 0);
+               bd += sizeof(struct qe_bd);
+       }
+       bd -= sizeof(struct qe_bd);
+       /* set bd status and length */
+       out_be32((u32*)bd, T_W);        /* for last BD set Wrap bit */
+
+       /* Init Rx bds */
+       bd = uccs->rx_bd = qe_muram_addr(uccs->rx_base_offset);
+       for (i = 0; i < us_info->rx_bd_ring_len; i++) {
+               /* set bd status and length */
+               out_be32((u32*)bd, 0);
+               /* clear bd buffer */
+               out_be32(&(((struct qe_bd *)bd)->buf), 0);
+               bd += sizeof(struct qe_bd);
+       }
+       bd -= sizeof(struct qe_bd);
+       /* set bd status and length */
+       out_be32((u32*)bd, R_W);        /* for last BD set Wrap bit */
+
+       /* Set GUMR (For more details see the hardware spec.). */
+       /* gumr_h */
+       gumr = 0;
+       gumr |= us_info->tcrc;
+       if (us_info->cdp)
+               gumr |= UCC_SLOW_GUMR_H_CDP;
+       if (us_info->ctsp)
+               gumr |= UCC_SLOW_GUMR_H_CTSP;
+       if (us_info->cds)
+               gumr |= UCC_SLOW_GUMR_H_CDS;
+       if (us_info->ctss)
+               gumr |= UCC_SLOW_GUMR_H_CTSS;
+       if (us_info->tfl)
+               gumr |= UCC_SLOW_GUMR_H_TFL;
+       if (us_info->rfw)
+               gumr |= UCC_SLOW_GUMR_H_RFW;
+       if (us_info->txsy)
+               gumr |= UCC_SLOW_GUMR_H_TXSY;
+       if (us_info->rtsm)
+               gumr |= UCC_SLOW_GUMR_H_RTSM;
+       out_be32(&us_regs->gumr_h, gumr);
+
+       /* gumr_l */
+       gumr = 0;
+       if (us_info->tci)
+               gumr |= UCC_SLOW_GUMR_L_TCI;
+       if (us_info->rinv)
+               gumr |= UCC_SLOW_GUMR_L_RINV;
+       if (us_info->tinv)
+               gumr |= UCC_SLOW_GUMR_L_TINV;
+       if (us_info->tend)
+               gumr |= UCC_SLOW_GUMR_L_TEND;
+       gumr |= us_info->tdcr;
+       gumr |= us_info->rdcr;
+       gumr |= us_info->tenc;
+       gumr |= us_info->renc;
+       gumr |= us_info->diag;
+       gumr |= us_info->mode;
+       out_be32(&us_regs->gumr_l, gumr);
+
+       /* Function code registers */
+       /* function_code has initial value 0 */
+
+       /* if the data is in cachable memory, the 'global' */
+       /* in the function code should be set. */
+       function_code |= us_info->data_mem_part;
+       function_code |= QE_BMR_BYTE_ORDER_BO_MOT;      /* Required for QE */
+       uccs->us_pram->tfcr = function_code;
+       uccs->us_pram->rfcr = function_code;
+
+       /* rbase, tbase are offsets from MURAM base */
+       out_be16(&uccs->us_pram->rbase, uccs->us_pram_offset);
+       out_be16(&uccs->us_pram->tbase, uccs->us_pram_offset);
+
+       /* Mux clocking */
+       /* Grant Support */
+       ucc_set_qe_mux_grant(us_info->ucc_num, us_info->grant_support);
+       /* Breakpoint Support */
+       ucc_set_qe_mux_bkpt(us_info->ucc_num, us_info->brkpt_support);
+       /* Set Tsa or NMSI mode. */
+       ucc_set_qe_mux_tsa(us_info->ucc_num, us_info->tsa);
+       /* If NMSI (not Tsa), set Tx and Rx clock. */
+       if (!us_info->tsa) {
+               /* Rx clock routing */
+               if (ucc_set_qe_mux_rxtx
+                   (us_info->ucc_num, us_info->rx_clock, COMM_DIR_RX)) {
+                       uccs_err
+                           ("ucc_slow_init: Illegal value for parameter"
+                               " 'RxClock'.");
+                       ucc_slow_free(uccs);
+                       return -EINVAL;
+               }
+               /* Tx clock routing */
+               if (ucc_set_qe_mux_rxtx(us_info->ucc_num,
+                                us_info->tx_clock, COMM_DIR_TX)) {
+                       uccs_err
+                           ("ucc_slow_init: Illegal value for parameter "
+                               "'TxClock'.");
+                       ucc_slow_free(uccs);
+                       return -EINVAL;
+               }
+       }
+
+       /*
+        * INTERRUPTS
+        */
+       /* Set interrupt mask register at UCC level. */
+       out_be16(&us_regs->uccm, us_info->uccm_mask);
+
+       /* First, clear anything pending at UCC level, */
+       /* otherwise, old garbage may come through */
+       /* as soon as the dam is opened. */
+
+       /* Writing '1' clears */
+       out_be16(&us_regs->ucce, 0xffff);
+
+       /* Issue QE Init command */
+       if (us_info->init_tx && us_info->init_rx)
+               command = QE_INIT_TX_RX;
+       else if (us_info->init_tx)
+               command = QE_INIT_TX;
+       else
+               command = QE_INIT_RX;   /* We know at least one is TRUE */
+       id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
+       qe_issue_cmd(command, id, QE_CR_PROTOCOL_UNSPECIFIED, 0);
+
+       *uccs_ret = uccs;
+       return 0;
+}
+
+void ucc_slow_free(struct ucc_slow_private * uccs)
+{
+       if (!uccs)
+               return;
+
+       if (uccs->rx_base_offset)
+               qe_muram_free(uccs->rx_base_offset);
+
+       if (uccs->tx_base_offset)
+               qe_muram_free(uccs->tx_base_offset);
+
+       if (uccs->us_pram) {
+               qe_muram_free(uccs->us_pram_offset);
+               uccs->us_pram = NULL;
+       }
+
+       kfree(uccs);
+}
index 8adad1444a51f3fca949bc4d0e7ec3ead0f3d93e..708236f3474612a2aad9fc252a458cf1d270e7fc 100644 (file)
@@ -2,6 +2,8 @@
  * Routines providing a simple monitor for use on the PowerMac.
  *
  * Copyright (C) 1996-2005 Paul Mackerras.
+ * Copyright (C) 2001 PPC64 Team, IBM Corp
+ * Copyrignt (C) 2006 Michael Ellerman, IBM Corp
  *
  *      This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -503,7 +505,7 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
 
        mtmsr(msr);             /* restore interrupt enable */
 
-       return cmd != 'X';
+       return cmd != 'X' && cmd != EOF;
 }
 
 int xmon(struct pt_regs *excp)
@@ -2597,3 +2599,34 @@ static int __init setup_xmon_sysrq(void)
 }
 __initcall(setup_xmon_sysrq);
 #endif /* CONFIG_MAGIC_SYSRQ */
+
+int __initdata xmon_early, xmon_off;
+
+static int __init early_parse_xmon(char *p)
+{
+       if (!p || strncmp(p, "early", 5) == 0) {
+               /* just "xmon" is equivalent to "xmon=early" */
+               xmon_init(1);
+               xmon_early = 1;
+       } else if (strncmp(p, "on", 2) == 0)
+               xmon_init(1);
+       else if (strncmp(p, "off", 3) == 0)
+               xmon_off = 1;
+       else if (strncmp(p, "nobt", 4) == 0)
+               xmon_no_auto_backtrace = 1;
+       else
+               return 1;
+
+       return 0;
+}
+early_param("xmon", early_parse_xmon);
+
+void __init xmon_setup(void)
+{
+#ifdef CONFIG_XMON_DEFAULT
+       if (!xmon_off)
+               xmon_init(1);
+#endif
+       if (xmon_early)
+               debugger(NULL);
+}
index b81a367dc2780bb15e49545e1d8ac92fe73a4d24..87fe9a89dba710f1afd9d5c9f5b5ecb1a5a173f3 100644 (file)
@@ -1720,7 +1720,7 @@ static int siccuart_open(struct tty_struct *tty, struct file *filp)
     return 0;
 }
 
-static struct tty_operations sicc_ops = {
+static const struct tty_operations sicc_ops = {
        .open = siccuart_open,
        .close = siccuart_close,
        .write = siccuart_write,
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 29115e01f60adc8956b8cdec751916ed558b615b..1640c4199ca623294813f2dbee0d06d6b33590e6 100644 (file)
 #include <stdlib.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <netinet/in.h>
 #ifdef __sun__
 #include <inttypes.h>
 #else
 #include <stdint.h>
 #endif
 
-#ifdef __i386__
-#define cpu_to_be32(x) le32_to_cpu(x)
-#define cpu_to_be16(x) le16_to_cpu(x)
-#else
-#define cpu_to_be32(x) (x)
-#define cpu_to_be16(x) (x)
-#endif
-
-#define cpu_to_le32(x) le32_to_cpu((x))
-unsigned long le32_to_cpu(unsigned long x)
-{
-       return (((x & 0x000000ffU) << 24) |
-               ((x & 0x0000ff00U) <<  8) |
-               ((x & 0x00ff0000U) >>  8) |
-               ((x & 0xff000000U) >> 24));
-}
-
-#define cpu_to_le16(x) le16_to_cpu((x))
-unsigned short le16_to_cpu(unsigned short x)
-{
-       return (((x & 0x00ff) << 8) |
-               ((x & 0xff00) >> 8));
-}
-
 /* size of read buffer */
 #define SIZE 0x1000
 
@@ -62,124 +39,109 @@ typedef struct bug_boot_header {
 
 #define HEADER_SIZE    sizeof(bug_boot_header_t)
 
-uint32_t copy_image(int32_t in_fd, int32_t out_fd)
+void update_checksum(void *buf, size_t size, uint16_t *sum)
 {
-  uint8_t buf[SIZE];
-  int n;
-  uint32_t image_size = 0;
-  uint8_t zero = 0;
-
-  lseek(in_fd, ELF_HEADER_SIZE, SEEK_SET);
-
-  /* Copy an image while recording its size */
-  while ( (n = read(in_fd, buf, SIZE)) > 0 )
-    {
-    image_size = image_size + n;
-    write(out_fd, buf, n);
-    }
-
-  /* BUG romboot requires that our size is divisible by 2 */
-  /* align image to 2 byte boundary */
-  if (image_size % 2)
-    {
-    image_size++;
-    write(out_fd, &zero, 1);
-    }
-
-  return image_size;
+       uint32_t csum = *sum;
+
+       while (size) {
+               csum += *(uint16_t *)buf;
+               if (csum > 0xffff)
+                       csum -= 0xffff;
+               buf = (uint16_t *)buf + 1;
+               size -= 2;
+       }
+       *sum = csum;
 }
 
-void write_bugboot_header(int32_t out_fd, uint32_t boot_size)
+uint32_t copy_image(int in_fd, int out_fd, uint16_t *sum)
 {
-  uint8_t header_block[HEADER_SIZE];
-  bug_boot_header_t *bbh = (bug_boot_header_t *)&header_block[0];
-
-  memset(header_block, 0, HEADER_SIZE);
-
-  /* Fill in the PPCBUG ROM boot header */
-  strncpy(bbh->magic_word, "BOOT", 4);         /* PPCBUG magic word */
-  bbh->entry_offset = cpu_to_be32(HEADER_SIZE);        /* Entry address */
-  bbh->routine_length= cpu_to_be32(HEADER_SIZE+boot_size+2);   /* Routine length */
-  strncpy(bbh->routine_name, "LINUXROM", 8);           /* Routine name   */
-
-  /* Output the header and bootloader to the file */
-  write(out_fd, header_block, HEADER_SIZE);
+       uint8_t buf[SIZE];
+       int offset = 0;
+       int n;
+       uint32_t image_size = 0;
+
+       lseek(in_fd, ELF_HEADER_SIZE, SEEK_SET);
+
+       /* Copy an image while recording its size */
+       while ( (n = read(in_fd, buf + offset, SIZE - offset)) > 0 ) {
+               n += offset;
+               offset = n & 1;
+               n -= offset;
+               image_size = image_size + n;
+               /* who's going to deal with short writes? */
+               write(out_fd, buf, n);
+               update_checksum(buf, n, sum);
+               if (offset)
+                       buf[0] = buf[n];
+       }
+
+       /* BUG romboot requires that our size is divisible by 2 */
+       /* align image to 2 byte boundary */
+       if (offset) {
+               image_size += 2;
+               buf[1] = '\0';
+               write(out_fd, buf, 2);
+               update_checksum(buf, 2, sum);
+       }
+       return image_size;
 }
 
-uint16_t calc_checksum(int32_t bug_fd)
+void write_bugboot_header(int out_fd, uint32_t boot_size, uint16_t *sum)
 {
-  uint32_t checksum_var = 0;
-  uint8_t buf[2];
-  int n;
-
-  /* Checksum loop */
-  while ( (n = read(bug_fd, buf, 2) ) )
-  {
-    checksum_var = checksum_var + *(uint16_t *)buf;
-
-    /* If we carry out, mask it and add one to the checksum */
-    if (checksum_var >> 16)
-      checksum_var = (checksum_var & 0x0000ffff) + 1;
-  }
-
-  return checksum_var;
+       static bug_boot_header_t bbh = {
+               .magic_word = "BOOT",
+               .routine_name = "LINUXROM"
+       };
+
+       /* Fill in the PPCBUG ROM boot header */
+       bbh.entry_offset = htonl(HEADER_SIZE);  /* Entry address */
+       bbh.routine_length= htonl(HEADER_SIZE+boot_size+2);     /* Routine length */
+
+       /* Output the header and bootloader to the file */
+       write(out_fd, &bbh, sizeof(bug_boot_header_t));
+       update_checksum(&bbh, sizeof(bug_boot_header_t), sum);
 }
 
 int main(int argc, char *argv[])
 {
-  int32_t image_fd, bugboot_fd;
-  int argptr = 1;
-  uint32_t kernel_size = 0;
-  uint16_t checksum = 0;
-  uint8_t bugbootname[256];
-
-  if ( (argc != 3) )
-  {
-    fprintf(stderr, "usage: %s <kernel_image> <bugboot>\n",argv[0]);
-    exit(-1);
-  }
-
-  /* Get file args */
-
-  /* kernel image file */
-    if ((image_fd = open( argv[argptr] , 0)) < 0)
-      exit(-1);
-  argptr++;
+       int image_fd, bugboot_fd;
+       uint32_t kernel_size = 0;
+       uint16_t checksum = 0;
 
-  /* bugboot file */
-  if ( !strcmp( argv[argptr], "-" ) )
-    bugboot_fd = 1;                    /* stdout */
-  else
-    if ((bugboot_fd = creat( argv[argptr] , 0755)) < 0)
-      exit(-1);
-    else
-      strcpy(bugbootname, argv[argptr]);
-  argptr++;
+       if (argc != 3) {
+               fprintf(stderr, "usage: %s <kernel_image> <bugboot>\n",argv[0]);
+               exit(-1);
+       }
 
-  /* Set file position after ROM header block where zImage will be written */
-  lseek(bugboot_fd, HEADER_SIZE, SEEK_SET);
+       /* Get file args */
 
-  /* Copy kernel image into bugboot image */
-  kernel_size = copy_image(image_fd, bugboot_fd);
-  close(image_fd);
+       /* kernel image file */
+       if ((image_fd = open(argv[1] , 0)) < 0)
+               exit(-1);
 
-  /* Set file position to beginning where header/romboot will be written */
-  lseek(bugboot_fd, 0, SEEK_SET);
+       /* bugboot file */
+       if (!strcmp(argv[2], "-"))
+               bugboot_fd = 1;                 /* stdout */
+       else if ((bugboot_fd = creat(argv[2] , 0755)) < 0)
+               exit(-1);
 
-  /* Write out BUG header/romboot */
-  write_bugboot_header(bugboot_fd, kernel_size);
+       /* Set file position after ROM header block where zImage will be written */
+       lseek(bugboot_fd, HEADER_SIZE, SEEK_SET);
 
-  /* Close bugboot file */
-  close(bugboot_fd);
+       /* Copy kernel image into bugboot image */
+       kernel_size = copy_image(image_fd, bugboot_fd, &checksum);
 
-  /* Reopen it as read/write */
-  bugboot_fd = open(bugbootname, O_RDWR);
+       /* Set file position to beginning where header/romboot will be written */
+       lseek(bugboot_fd, 0, SEEK_SET);
 
-  /* Calculate checksum */
-  checksum = calc_checksum(bugboot_fd);
+       /* Write out BUG header/romboot */
+       write_bugboot_header(bugboot_fd, kernel_size, &checksum);
 
-  /* Write out the calculated checksum */
-  write(bugboot_fd, &checksum, 2);
+       /* Write out the calculated checksum */
+       lseek(bugboot_fd, 0, SEEK_END);
+       write(bugboot_fd, &checksum, 2);
 
-  return 0;
+       /* Close bugboot file */
+       close(bugboot_fd);
+       return 0;
 }
index f6d5a2f2fcf658e8a6e5d20d83a3d8d47f15ead3..192bb397126fac25f5eae2901316252dc19803e6 100644 (file)
  * Modified for Sparc hosted builds by Peter Wahl <PeterWahl@web.de>
  */
 
-#include <fcntl.h>
 #include <stdio.h>
-#include <stdlib.h>
 #include <string.h>
-#include <strings.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#define cpu_to_le32(x) le32_to_cpu((x))
-unsigned long le32_to_cpu(unsigned long x)
-{
-       return (((x & 0x000000ffU) << 24) |
-               ((x & 0x0000ff00U) <<  8) |
-               ((x & 0x00ff0000U) >>  8) |
-               ((x & 0xff000000U) >> 24));
-}
-
-
-#define cpu_to_le16(x) le16_to_cpu((x))
-unsigned short le16_to_cpu(unsigned short x)
-{
-       return (((x & 0x00ff) << 8) |
-               ((x & 0xff00) >> 8));
-}
-
-#define cpu_to_be32(x) (x)
-#define be32_to_cpu(x) (x)
-#define cpu_to_be16(x) (x)
-#define be16_to_cpu(x) (x)
+#include <stdlib.h>
 
 /* size of read buffer */
 #define SIZE 0x1000
 
-
-typedef unsigned long dword_t;
-typedef unsigned short word_t;
-typedef unsigned char byte_t;
-typedef byte_t block_t[512];
-typedef byte_t page_t[4096];
-
-
 /*
  * Partition table entry
  *  - from the PReP spec
  */
 typedef struct partition_entry {
-  byte_t       boot_indicator;
-  byte_t       starting_head;
-  byte_t       starting_sector;
-  byte_t       starting_cylinder;
-
-  byte_t       system_indicator;
-  byte_t       ending_head;
-  byte_t       ending_sector;
-  byte_t       ending_cylinder;
-
-  dword_t      beginning_sector;
-  dword_t      number_of_sectors;
+       unsigned char boot_indicator;
+       unsigned char starting_head;
+       unsigned char starting_sector;
+       unsigned char starting_cylinder;
+
+       unsigned char system_indicator;
+       unsigned char ending_head;
+       unsigned char ending_sector;
+       unsigned char ending_cylinder;
+
+       unsigned char beginning_sector[4];
+       unsigned char number_of_sectors[4];
 } partition_entry_t;
 
 #define BootActive     0x80
 #define SystemPrep     0x41
 
-void copy_image(int , int);
-void write_prep_partition(int , int );
-void write_asm_data( int in, int out );
+void copy_image(FILE *, FILE *);
+void write_prep_partition(FILE *, FILE *);
+void write_asm_data(FILE *, FILE *);
 
 unsigned int elfhdr_size = 65536;
 
 int main(int argc, char *argv[])
 {
-  int in_fd, out_fd;
-  int argptr = 1;
-  unsigned int prep = 0;
-  unsigned int asmoutput = 0;
-
-  if ( (argc < 3) || (argc > 4) )
-  {
-    fprintf(stderr, "usage: %s [-pbp] [-asm] <boot-file> <image>\n",argv[0]);
-    exit(-1);
-  }
-
-  /* needs to handle args more elegantly -- but this is a small/simple program */
-
-  /* check for -pbp */
-  if ( !strcmp( argv[argptr], "-pbp" ) )
-  {
-    prep = 1;
-    argptr++;
-  }
-
-  /* check for -asm */
-  if ( !strcmp( argv[argptr], "-asm" ) )
-  {
-    asmoutput = 1;
-    argptr++;
-  }
-
-  /* input file */
-  if ( !strcmp( argv[argptr], "-" ) )
-    in_fd = 0;                 /* stdin */
-  else
-    if ((in_fd = open( argv[argptr] , 0)) < 0)
-      exit(-1);
-  argptr++;
-
-  /* output file */
-  if ( !strcmp( argv[argptr], "-" ) )
-    out_fd = 1;                        /* stdout */
-  else
-    if ((out_fd = creat( argv[argptr] , 0755)) < 0)
-      exit(-1);
-  argptr++;
-
-  /* skip elf header in input file */
-  /*if ( !prep )*/
-  lseek(in_fd, elfhdr_size, SEEK_SET);
-
-  /* write prep partition if necessary */
-  if ( prep )
-         write_prep_partition( in_fd, out_fd );
-
-  /* write input image to bootimage */
-  if ( asmoutput )
-         write_asm_data( in_fd, out_fd );
-  else
-         copy_image(in_fd, out_fd);
-
-  return 0;
+       FILE *in, *out;
+       int argptr = 1;
+       int prep = 0;
+       int asmoutput = 0;
+
+       if (argc < 3 || argc > 4) {
+               fprintf(stderr, "usage: %s [-pbp] [-asm] <boot-file> <image>\n",
+                       argv[0]);
+               exit(-1);
+       }
+
+/* needs to handle args more elegantly -- but this is a small/simple program */
+
+       /* check for -pbp */
+       if (!strcmp(argv[argptr], "-pbp")) {
+               prep = 1;
+               argptr++;
+       }
+
+       /* check for -asm */
+       if (!strcmp(argv[argptr], "-asm")) {
+               asmoutput = 1;
+               argptr++;
+       }
+
+       /* input file */
+       if (!strcmp(argv[argptr], "-"))
+               in = stdin;
+       else if (!(in = fopen(argv[argptr], "r")))
+               exit(-1);
+       argptr++;
+
+       /* output file */
+       if (!strcmp(argv[argptr], "-"))
+               out = stdout;
+       else if (!(out = fopen(argv[argptr], "w")))
+               exit(-1);
+       argptr++;
+
+       /* skip elf header in input file */
+       /*if ( !prep )*/
+       fseek(in, elfhdr_size, SEEK_SET);
+
+       /* write prep partition if necessary */
+       if (prep)
+               write_prep_partition(in, out);
+
+       /* write input image to bootimage */
+       if (asmoutput)
+               write_asm_data(in, out);
+       else
+               copy_image(in, out);
+
+       return 0;
 }
 
-void write_prep_partition(int in, int out)
+void store_le32(unsigned int v, unsigned char *p)
 {
-  unsigned char block[512];
-  partition_entry_t pe;
-  dword_t *entry  = (dword_t *)&block[0];
-  dword_t *length = (dword_t *)&block[sizeof(long)];
-  struct stat info;
-
-  if (fstat(in, &info) < 0)
-  {
-    fprintf(stderr,"info failed\n");
-    exit(-1);
-  }
-
-  bzero( block, sizeof block );
-
-  /* set entry point and boot image size skipping over elf header */
-#ifdef __i386__
-  *entry = 0x400/*+65536*/;
-  *length = info.st_size-elfhdr_size+0x400;
-#else
-  *entry = cpu_to_le32(0x400/*+65536*/);
-  *length = cpu_to_le32(info.st_size-elfhdr_size+0x400);
-#endif /* __i386__ */
-
-  /* sets magic number for msdos partition (used by linux) */
-  block[510] = 0x55;
-  block[511] = 0xAA;
-
-  /*
-   * Build a "PReP" partition table entry in the boot record
-   *  - "PReP" may only look at the system_indicator
-   */
-  pe.boot_indicator   = BootActive;
-  pe.system_indicator = SystemPrep;
-  /*
-   * The first block of the diskette is used by this "boot record" which
-   * actually contains the partition table. (The first block of the
-   * partition contains the boot image, but I digress...)  We'll set up
-   * one partition on the diskette and it shall contain the rest of the
-   * diskette.
-   */
-  pe.starting_head     = 0;    /* zero-based                        */
-  pe.starting_sector   = 2;    /* one-based                         */
-  pe.starting_cylinder = 0;    /* zero-based                        */
-  pe.ending_head       = 1;    /* assumes two heads                 */
-  pe.ending_sector     = 18;   /* assumes 18 sectors/track          */
-  pe.ending_cylinder   = 79;   /* assumes 80 cylinders/diskette     */
-
-  /*
-   * The "PReP" software ignores the above fields and just looks at
-   * the next two.
-   *   - size of the diskette is (assumed to be)
-   *     (2 tracks/cylinder)(18 sectors/tracks)(80 cylinders/diskette)
-   *   - unlike the above sector numbers, the beginning sector is zero-based!
-   */
+       p[0] = v;
+       p[1] = v >>= 8;
+       p[2] = v >>= 8;
+       p[3] = v >> 8;
+}
+
+void write_prep_partition(FILE *in, FILE *out)
+{
+       unsigned char block[512];
+       partition_entry_t pe;
+       unsigned char *entry  = block;
+       unsigned char *length = block + 4;
+       long pos = ftell(in), size;
+
+       if (fseek(in, 0, SEEK_END) < 0) {
+               fprintf(stderr,"info failed\n");
+               exit(-1);
+       }
+       size = ftell(in);
+       if (fseek(in, pos, SEEK_SET) < 0) {
+               fprintf(stderr,"info failed\n");
+               exit(-1);
+       }
+
+       memset(block, '\0', sizeof(block));
+
+       /* set entry point and boot image size skipping over elf header */
+       store_le32(0x400/*+65536*/, entry);
+       store_le32(size-elfhdr_size+0x400, length);
+
+       /* sets magic number for msdos partition (used by linux) */
+       block[510] = 0x55;
+       block[511] = 0xAA;
+
+       /*
+       * Build a "PReP" partition table entry in the boot record
+       *  - "PReP" may only look at the system_indicator
+       */
+       pe.boot_indicator   = BootActive;
+       pe.system_indicator = SystemPrep;
+       /*
+       * The first block of the diskette is used by this "boot record" which
+       * actually contains the partition table. (The first block of the
+       * partition contains the boot image, but I digress...)  We'll set up
+       * one partition on the diskette and it shall contain the rest of the
+       * diskette.
+       */
+       pe.starting_head     = 0;       /* zero-based                        */
+       pe.starting_sector   = 2;       /* one-based                         */
+       pe.starting_cylinder = 0;       /* zero-based                        */
+       pe.ending_head       = 1;       /* assumes two heads                 */
+       pe.ending_sector     = 18;      /* assumes 18 sectors/track          */
+       pe.ending_cylinder   = 79;      /* assumes 80 cylinders/diskette     */
+
+       /*
+       * The "PReP" software ignores the above fields and just looks at
+       * the next two.
+       *   - size of the diskette is (assumed to be)
+       *     (2 tracks/cylinder)(18 sectors/tracks)(80 cylinders/diskette)
+       *   - unlike the above sector numbers, the beginning sector is zero-based!
+       */
 #if 0
-  pe.beginning_sector  = cpu_to_le32(1);
-#else
-  /* This has to be 0 on the PowerStack? */
-#ifdef __i386__
-  pe.beginning_sector  = 0;
+       store_le32(1, pe.beginning_sector);
 #else
-  pe.beginning_sector  = cpu_to_le32(0);
-#endif /* __i386__ */
+       /* This has to be 0 on the PowerStack? */
+       store_le32(0, pe.beginning_sector);
 #endif
 
-#ifdef __i386__
-  pe.number_of_sectors = 2*18*80-1;
-#else
-  pe.number_of_sectors = cpu_to_le32(2*18*80-1);
-#endif /* __i386__ */
+       store_le32(2*18*80-1, pe.number_of_sectors);
 
-  memcpy(&block[0x1BE], &pe, sizeof(pe));
+       memcpy(&block[0x1BE], &pe, sizeof(pe));
 
-  write( out, block, sizeof(block) );
-  write( out, entry, sizeof(*entry) );
-  write( out, length, sizeof(*length) );
-  /* set file position to 2nd sector where image will be written */
-  lseek( out, 0x400, SEEK_SET );
+       fwrite(block, sizeof(block), 1, out);
+       fwrite(entry, 4, 1, out);
+       fwrite(length, 4, 1, out);
+       /* set file position to 2nd sector where image will be written */
+       fseek( out, 0x400, SEEK_SET );
 }
 
 
 
-void
-copy_image(int in, int out)
+void copy_image(FILE *in, FILE *out)
 {
-  char buf[SIZE];
-  int n;
+       char buf[SIZE];
+       int n;
 
-  while ( (n = read(in, buf, SIZE)) > 0 )
-    write(out, buf, n);
+       while ( (n = fread(buf, 1, SIZE, in)) > 0 )
+               fwrite(buf, 1, n, out);
 }
 
 
 void
-write_asm_data( int in, int out )
+write_asm_data(FILE *in, FILE *out)
 {
-  int i, cnt, pos, len;
-  unsigned int cksum, val;
-  unsigned char *lp;
-  unsigned char buf[SIZE];
-  unsigned char str[256];
-
-  write( out, "\t.data\n\t.globl input_data\ninput_data:\n",
-        strlen( "\t.data\n\t.globl input_data\ninput_data:\n" ) );
-  pos = 0;
-  cksum = 0;
-  while ((len = read(in, buf, sizeof(buf))) > 0)
-  {
-    cnt = 0;
-    lp = (unsigned char *)buf;
-    len = (len + 3) & ~3;  /* Round up to longwords */
-    for (i = 0;  i < len;  i += 4)
-    {
-      if (cnt == 0)
-      {
-       write( out, "\t.long\t", strlen( "\t.long\t" ) );
-      }
-      sprintf( str, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]);
-      write( out, str, strlen(str) );
-      val = *(unsigned long *)lp;
-      cksum ^= val;
-      lp += 4;
-      if (++cnt == 4)
-      {
-       cnt = 0;
-       sprintf( str, " # %x \n", pos+i-12);
-       write( out, str, strlen(str) );
-      } else
-      {
-       write( out, ",", 1 );
-      }
-    }
-    if (cnt)
-    {
-      write( out, "0\n", 2 );
-    }
-    pos += len;
-  }
-  sprintf(str, "\t.globl input_len\ninput_len:\t.long\t0x%x\n", pos);
-  write( out, str, strlen(str) );
-
-  fprintf(stderr, "cksum = %x\n", cksum);
+       int i, cnt, pos = 0;
+       unsigned int cksum = 0, val;
+       unsigned char *lp;
+       unsigned char buf[SIZE];
+       size_t len;
+
+       fputs("\t.data\n\t.globl input_data\ninput_data:\n", out);
+       while ((len = fread(buf, 1, sizeof(buf), in)) > 0) {
+               cnt = 0;
+               lp = buf;
+               /* Round up to longwords */
+               while (len & 3)
+                       buf[len++] = '\0';
+               for (i = 0;  i < len;  i += 4) {
+                       if (cnt == 0)
+                               fputs("\t.long\t", out);
+                       fprintf(out, "0x%02X%02X%02X%02X",
+                               lp[0], lp[1], lp[2], lp[3]);
+                       val = *(unsigned long *)lp;
+                       cksum ^= val;
+                       lp += 4;
+                       if (++cnt == 4) {
+                               cnt = 0;
+                               fprintf(out, " # %x \n", pos+i-12);
+                       } else {
+                               fputs(",", out);
+                       }
+               }
+               if (cnt)
+                       fputs("0\n", out);
+               pos += len;
+       }
+       fprintf(out, "\t.globl input_len\ninput_len:\t.long\t0x%x\n", pos);
+       fprintf(stderr, "cksum = %x\n", cksum);
 }
index 50b4bbd06804b123a443ab0420e824a1ebaf2bc8..5f6684012ded76d4d02c9b0f55c37b8e2cb6548f 100644 (file)
@@ -942,20 +942,16 @@ _GLOBAL(kernel_thread)
        addi    r1,r1,16
        blr
 
+_GLOBAL(kernel_execve)
+       li      r0,__NR_execve
+       sc
+       bnslr
+       neg     r3,r3
+       blr
+
 /*
  * This routine is just here to keep GCC happy - sigh...
  */
 _GLOBAL(__main)
        blr
 
-#define SYSCALL(name) \
-_GLOBAL(name) \
-       li      r0,__NR_##name; \
-       sc; \
-       bnslr; \
-       lis     r4,errno@ha; \
-       stw     r3,errno@l(r4); \
-       li      r3,-1; \
-       blr
-
-SYSCALL(execve)
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 2a35fe2b9b9652784d80e9a1a0d8ddd629725e04..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
  *
@@ -103,7 +103,7 @@ static struct fs_platform_info mpc82xx_enet_pdata[] = {
        },
 };
 
-static void init_fcc1_ioports(void)
+static void init_fcc1_ioports(struct fs_platform_info*)
 {
        struct io_port *io;
        u32 tempval;
@@ -144,7 +144,7 @@ static void init_fcc1_ioports(void)
        iounmap(immap);
 }
 
-static void init_fcc2_ioports(void)
+static void init_fcc2_ioports(struct fs_platform_info*)
 {
        cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
        u32 *bcsr = ioremap(BCSR_ADDR+12, sizeof(u32));
@@ -229,7 +229,7 @@ static void mpc8272ads_fixup_uart_pdata(struct platform_device *pdev,
        }
 }
 
-static void init_scc1_uart_ioports(void)
+static void init_scc1_uart_ioports(struct fs_uart_platform_info*)
 {
        cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
 
@@ -246,7 +246,7 @@ static void init_scc1_uart_ioports(void)
        iounmap(immap);
 }
 
-static void init_scc4_uart_ioports(void)
+static void init_scc4_uart_ioports(struct fs_uart_platform_info*)
 {
        cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
 
index e12cece4c9fd056e1a2586d2feabc996d986ef7d..5f130dca377009cbe3d13d8294f9ce9ee62b025b 100644 (file)
@@ -137,7 +137,7 @@ void __init board_init(void)
        iounmap(bcsr_io);
 }
 
-static void setup_fec1_ioports(void)
+static void setup_fec1_ioports(struct fs_platform_info*)
 {
        immap_t *immap = (immap_t *) IMAP_ADDR;
 
@@ -145,7 +145,7 @@ static void setup_fec1_ioports(void)
        setbits16(&immap->im_ioport.iop_pddir, 0x1fff);
 }
 
-static void setup_scc1_ioports(void)
+static void setup_scc1_ioports(struct fs_platform_info*)
 {
        immap_t *immap = (immap_t *) IMAP_ADDR;
        unsigned *bcsr_io;
@@ -194,7 +194,7 @@ static void setup_scc1_ioports(void)
 
 }
 
-static void setup_smc1_ioports(void)
+static void setup_smc1_ioports(struct fs_uart_platform_info*)
 {
        immap_t *immap = (immap_t *) IMAP_ADDR;
        unsigned *bcsr_io;
@@ -216,7 +216,7 @@ static void setup_smc1_ioports(void)
 
 }
 
-static void setup_smc2_ioports(void)
+static void setup_smc2_ioports(struct fs_uart_platform_info*)
 {
        immap_t *immap = (immap_t *) IMAP_ADDR;
        unsigned *bcsr_io;
index 5dfa4e6c2af038e6c7d45578b68f07f44435f02f..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
  *
@@ -161,7 +161,7 @@ void __init board_init(void)
 #endif
 }
 
-static void setup_fec1_ioports(void)
+static void setup_fec1_ioports(struct fs_platform_info*)
 {
        immap_t *immap = (immap_t *) IMAP_ADDR;
 
@@ -181,7 +181,7 @@ static void setup_fec1_ioports(void)
        clrbits32(&immap->im_cpm.cp_cptr, 0x00000100);
 }
 
-static void setup_fec2_ioports(void)
+static void setup_fec2_ioports(struct fs_platform_info*)
 {
        immap_t *immap = (immap_t *) IMAP_ADDR;
 
@@ -193,7 +193,7 @@ static void setup_fec2_ioports(void)
        clrbits32(&immap->im_cpm.cp_cptr, 0x00000080);
 }
 
-static void setup_scc3_ioports(void)
+static void setup_scc3_ioports(struct fs_platform_info*)
 {
        immap_t *immap = (immap_t *) IMAP_ADDR;
        unsigned *bcsr_io;
@@ -315,7 +315,7 @@ static void __init mpc885ads_fixup_scc_enet_pdata(struct platform_device *pdev,
        mpc885ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1);
 }
 
-static void setup_smc1_ioports(void)
+static void setup_smc1_ioports(struct fs_uart_platform_info*)
 {
         immap_t *immap = (immap_t *) IMAP_ADDR;
         unsigned *bcsr_io;
@@ -335,7 +335,7 @@ static void setup_smc1_ioports(void)
         clrbits16(&immap->im_cpm.cp_pbodr, iobits);
 }
 
-static void setup_smc2_ioports(void)
+static void setup_smc2_ioports(struct fs_uart_platform_info*)
 {
         immap_t *immap = (immap_t *) IMAP_ADDR;
         unsigned *bcsr_io;
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 c46e3d48e4104d827abc7c17c40bed215fe70461..e15e1489aef56b5c89b54f52822234ba84a64935 100644 (file)
@@ -357,11 +357,16 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned
 
 int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
 {
+       compat_ino_t ino;
        int err;
 
        if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev))
                return -EOVERFLOW;
 
+       ino = stat->ino;
+       if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
+               return -EOVERFLOW;
+
        err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev);
        err |= put_user(stat->ino, &statbuf->st_ino);
        err |= put_user(stat->mode, &statbuf->st_mode);
index ca28fb0b3790f7c966e338f546bed0b18ac192fc..4d9ff5ce4cbdb41c04a78261ad8d98e579bb8891 100644 (file)
@@ -369,11 +369,12 @@ void __kprobes kretprobe_trampoline_holder(void)
 int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
 {
        struct kretprobe_instance *ri = NULL;
-       struct hlist_head *head;
+       struct hlist_head *head, empty_rp;
        struct hlist_node *node, *tmp;
        unsigned long flags, orig_ret_address = 0;
        unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
 
+       INIT_HLIST_HEAD(&empty_rp);
        spin_lock_irqsave(&kretprobe_lock, flags);
        head = kretprobe_inst_table_head(current);
 
@@ -399,7 +400,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
                        ri->rp->handler(ri, regs);
 
                orig_ret_address = (unsigned long)ri->ret_addr;
-               recycle_rp_inst(ri);
+               recycle_rp_inst(ri, &empty_rp);
 
                if (orig_ret_address != trampoline_address) {
                        /*
@@ -417,6 +418,10 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
        spin_unlock_irqrestore(&kretprobe_lock, flags);
        preempt_enable_no_resched();
 
+       hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
+               hlist_del(&ri->hlist);
+               kfree(ri);
+       }
        /*
         * By returning a non-zero value, we are telling
         * kprobe_handler() that we don't want the post_handler
index e351780bb660cab9ef1dbc503799969edb175eb1..584ed95f3380b07b61c151e9616efecf2a218e3c 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/file.h>
 #include <linux/utsname.h>
 #include <linux/personality.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 #include <asm/ipc.h>
@@ -266,3 +267,22 @@ s390_fadvise64_64(struct fadvise64_64_args __user *args)
        return sys_fadvise64_64(a.fd, a.offset, a.len, a.advice);
 }
 
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+       register const char *__arg1 asm("2") = filename;
+       register char *const*__arg2 asm("3") = argv;
+       register char *const*__arg3 asm("4") = envp;
+       register long __svcres asm("2");
+       asm volatile(
+               "svc %b1"
+               : "=d" (__svcres)
+               : "i" (__NR_execve),
+                 "0" (__arg1),
+                 "d" (__arg2),
+                 "d" (__arg3) : "memory");
+       return __svcres;
+}
index 1cc5c9b27bfdeae32671c58e61263d929c92f6e2..f6a0c44361682de8e34fdc1eec8c57a2d7977f7e 100644 (file)
@@ -377,7 +377,7 @@ config SH_PCLK_FREQ
        default "50000000" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7780
        default "60000000" if CPU_SUBTYPE_SH7751
        default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || \
-                             CPU_SUBTYPE_SH7760
+                             CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7705
        default "27000000" if CPU_SUBTYPE_SH73180 || CPU_SUBTYPE_SH7343
        default "66000000" if CPU_SUBTYPE_SH4_202
        help
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 ad0e712c29f6955681dff88ac49ad9bf8596062b..75f91aaae0777ab373cd476da69bd9e6bf5620bf 100644 (file)
@@ -6,7 +6,6 @@
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License.
  */
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/apm_bios.h>
 #include <linux/kernel.h>
index 0e501bcbd7a964a8dfe9da141cd9742a13eceb83..83d3272120645d149c16965e46d0f90b2f5c1183 100644 (file)
@@ -6,7 +6,6 @@
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License.
  */
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/suspend.h>
 #include <linux/errno.h>
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 a006d6443225fca54abf6f57b0dd29513d709d88..8f2e1c68b90fb7c61f9f25f6321f272e54ea5c46 100644 (file)
@@ -14,8 +14,6 @@
  * modified by kogiidena
  * 2005.03.03
  */
-
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <asm/io.h>
@@ -83,7 +81,7 @@ static struct hw_interrupt_type landisk_irq_type = {
 static void make_landisk_irq(unsigned int irq)
 {
        disable_irq_nosync(irq);
-       irq_desc[irq].handler = &landisk_irq_type;
+       irq_desc[irq].chip = &landisk_irq_type;
        disable_landisk_irq(irq);
 }
 
index e75cb578a28becfc1ec87c7c160dda9b10f7d3b5..0b7bee1a9ca5af99c0c3bdeb33aa0a8370f39174 100644 (file)
@@ -11,8 +11,6 @@
  *
  * LED control drive function added by kogiidena
  */
-
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/signal.h>
index 35ba726a097962718206fa62c53134c0fb035715..0a9a2a2ad05b7916e318258b9508e96fe2cd8586 100644 (file)
@@ -8,8 +8,6 @@
  * modifed by kogiidena
  * 2005.09.16
  */
-
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
index 127b9e020e0087e2b65cb87f488f7801a7769ce1..122d6996263763dc43a785ddae91b0f36a6fa808 100644 (file)
@@ -16,7 +16,6 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  */
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/pm.h>
 #include <linux/mm.h>
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 61d5e5d3c2949575d10e8d358f0e10df17877fe3..2d960e9a3143b5bae8c2061b0c0bd4e4dfd4915e 100644 (file)
@@ -8,8 +8,6 @@
  * Modified for R7780RP-1 by
  * Atom Create Engineering Co., Ltd. 2002.
  */
-
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <asm/io.h>
@@ -83,7 +81,7 @@ static struct hw_interrupt_type r7780rp_irq_type = {
 static void make_r7780rp_irq(unsigned int irq)
 {
        disable_irq_nosync(irq);
-       irq_desc[irq].handler = &r7780rp_irq_type;
+       irq_desc[irq].chip = &r7780rp_irq_type;
        disable_r7780rp_irq(irq);
 }
 
index 9f02766b6f531b1f1fc625bb7e7b34a5610f4d1c..6a00a257afd26e153373c2f2d7225f93311edd0e 100644 (file)
@@ -6,8 +6,6 @@
  *
  * This file contains Renesas Solutions HIGHLANDER R7780RP-1 specific LED code.
  */
-
-#include <linux/config.h>
 #include <linux/sched.h>
 #include <asm/io.h>
 #include <asm/r7780rp/r7780rp.h>
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 a8467bf90c2515d00df03feb1926931e9e7321f3..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
@@ -53,6 +53,6 @@ struct sh_machine_vector mv_7751systemh __initmv = {
        .mv_outsw               = sh7751systemh_outsw,
        .mv_outsl               = sh7751systemh_outsl,
 
-       .mv_init_irq            = sh7751system_init_irq,
+       .mv_init_irq            = sh7751systemh_init_irq,
 };
 ALIAS_MV(7751systemh)
index 646661a146ad38ad6c55a14c8258fe07552dbc1e..3a6d114249385ba390a20de148594f096027d26b 100644 (file)
@@ -4,8 +4,6 @@
  * I/O routine for SH-Mobile3AS 7343 SolutionEngine.
  *
  */
-
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <asm/io.h>
 #include <asm/mach/se7343.h>
index b41e3d4ea37c41af4a5f03e74f11522d5e5a8f83..288b62f59419990c8e50ab42a261308831278d24 100644 (file)
@@ -2,8 +2,6 @@
  * arch/sh/boards/se/7343/irq.c
  *
  */
-
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
@@ -73,7 +71,7 @@ static void
 make_intreq_irq(unsigned int irq)
 {
        disable_irq_nosync(irq);
-       irq_desc[irq].handler = &intreq_irq_type;
+       irq_desc[irq].chip = &intreq_irq_type;
        disable_intreq_irq(irq);
 }
 
index 6a439cf83e46334880b7ca27fef255c1d54fc1f4..6b39e191c4209ee8ac50b51d463625e2ec9cf321 100644 (file)
@@ -2,8 +2,6 @@
  * arch/sh/boards/se/7343/led.c
  *
  */
-
-#include <linux/config.h>
 #include <linux/sched.h>
 #include <asm/mach/se7343.h>
 
index 787322291fb34d4f77e4b66ff23cba8d990cdc37..c7d17fe7764ed2cbabd145726ea31b75912df125 100644 (file)
@@ -1,4 +1,3 @@
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <asm/machvec.h>
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 f3f82b7c821740b22849caadb665d82330fdca0c..a1d51d5fa925cbb56512a98cf913c2d40d27312b 100644 (file)
@@ -8,13 +8,10 @@
  *
  */
 #include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/hdreg.h>
-#include <linux/ide.h>
-#include <asm/io.h>
+#include <asm/machvec.h>
 #include <asm/se.h>
+#include <asm/io.h>
 #include <asm/smc37c93x.h>
-#include <asm/machvec.h>
 
 void heartbeat_se(void);
 void init_se_IRQ(void);
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 73e826310ba8748379395871c663681cbfa99939..f7e1dd39c8364c30db40874a04e391144f249b17 100644 (file)
@@ -8,12 +8,10 @@
  * Modified for 7751 Solution Engine by
  * Ian da Silva and Jeremy Siegel, 2001.
  */
-
 #include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/ide.h>
-#include <asm/io.h>
+#include <asm/machvec.h>
 #include <asm/se7751.h>
+#include <asm/io.h>
 
 void heartbeat_7751se(void);
 void init_7751se_IRQ(void);
index 6c310587ddfe72ecc15848d34297e1e52ec7f2b0..137e2ba9243e82a85f222e455f852f357df3a5d9 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <linux/init.h>
 #include <linux/irq.h>
+#include <linux/pci.h>
 #include <asm/io.h>
 #include <asm/rtc.h>
 #include <asm/sh03/io.h>
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)
diff --git a/arch/sh/boot/.gitignore b/arch/sh/boot/.gitignore
new file mode 100644 (file)
index 0000000..b6718de
--- /dev/null
@@ -0,0 +1 @@
+zImage
diff --git a/arch/sh/configs/adx_defconfig b/arch/sh/configs/adx_defconfig
deleted file mode 100644 (file)
index 353bfdc..0000000
+++ /dev/null
@@ -1,539 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar  2 15:09:26 2005
-#
-CONFIG_SUPERH=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_SWAP=y
-# CONFIG_SYSVIPC is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
-# CONFIG_IKCONFIG is not set
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
-# System type
-#
-# CONFIG_SH_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SOLUTION_ENGINE is not set
-# CONFIG_SH_7300_SOLUTION_ENGINE is not set
-# CONFIG_SH_73180_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
-# CONFIG_SH_EC3104 is not set
-# CONFIG_SH_SATURN is not set
-# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
-# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-CONFIG_SH_ADX=y
-# CONFIG_SH_MPC1211 is not set
-# CONFIG_SH_SH03 is not set
-# CONFIG_SH_SECUREEDGE5410 is not set
-# CONFIG_SH_HS7751RVOIP is not set
-# CONFIG_SH_RTS7751R2D is not set
-# CONFIG_SH_EDOSK7705 is not set
-# CONFIG_SH_SH4202_MICRODEV is not set
-# CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
-CONFIG_CPU_SH4=y
-# CONFIG_CPU_SUBTYPE_SH7604 is not set
-# CONFIG_CPU_SUBTYPE_SH7300 is not set
-# CONFIG_CPU_SUBTYPE_SH7705 is not set
-# CONFIG_CPU_SUBTYPE_SH7707 is not set
-# CONFIG_CPU_SUBTYPE_SH7708 is not set
-# CONFIG_CPU_SUBTYPE_SH7709 is not set
-CONFIG_CPU_SUBTYPE_SH7750=y
-# CONFIG_CPU_SUBTYPE_SH7751 is not set
-# CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
-# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
-# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
-CONFIG_MMU=y
-# CONFIG_CMDLINE_BOOL is not set
-CONFIG_MEMORY_START=0x08000000
-CONFIG_MEMORY_SIZE=0x00400000
-CONFIG_MEMORY_SET=y
-# CONFIG_MEMORY_OVERRIDE is not set
-CONFIG_CF_ENABLER=y
-# CONFIG_CF_AREA5 is not set
-CONFIG_CF_AREA6=y
-CONFIG_CF_BASE_ADDR=0xb8000000
-CONFIG_SH_RTC=y
-CONFIG_SH_FPU=y
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_PREEMPT is not set
-# CONFIG_UBC_WAKEUP is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
-# CONFIG_SH_STORE_QUEUES is not set
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
-CONFIG_SH_PCLK_FREQ=50000000
-
-#
-# CPU Frequency scaling
-#
-# CONFIG_CPU_FREQ is not set
-
-#
-# DMA support
-#
-# CONFIG_SH_DMA is not set
-
-#
-# Companion Chips
-#
-# CONFIG_HD6446X_SERIES is not set
-
-#
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
-#
-# CONFIG_PCI is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# PC-card bridges
-#
-
-#
-# PCI Hotplug Support
-#
-
-#
-# Executable file formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_FLAT is not set
-# CONFIG_BINFMT_MISC is not set
-
-#
-# SH initrd options
-#
-# CONFIG_EMBEDDED_RAMDISK is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
-# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-CONFIG_IDE_SH=y
-# CONFIG_IDE_ARM is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-# CONFIG_SCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Networking support
-#
-# CONFIG_NET is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-# CONFIG_SERIAL_SH_SCI is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# Dallas's 1-wire bus
-#
-# CONFIG_W1 is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-
-#
-# Graphics support
-#
-# CONFIG_FB is not set
-
-#
-# Console display driver support
-#
-CONFIG_VGA_CONSOLE=y
-CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# InfiniBand support
-#
-# CONFIG_INFINIBAND is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-# CONFIG_PROC_KCORE is not set
-CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
-# CONFIG_TMPFS is not set
-# CONFIG_HUGETLBFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-# CONFIG_NLS is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_FRAME_POINTER is not set
-CONFIG_SH_STANDARD_BIOS=y
-# CONFIG_EARLY_SCIF_CONSOLE is not set
-# CONFIG_EARLY_PRINTK is not set
-# CONFIG_KGDB is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Hardware crypto devices
-#
-
-#
-# Library routines
-#
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
diff --git a/arch/sh/configs/cqreek_defconfig b/arch/sh/configs/cqreek_defconfig
deleted file mode 100644 (file)
index 614662a..0000000
+++ /dev/null
@@ -1,533 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar  2 15:09:38 2005
-#
-CONFIG_SUPERH=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_SWAP=y
-# CONFIG_SYSVIPC is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
-# CONFIG_IKCONFIG is not set
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
-# System type
-#
-# CONFIG_SH_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SOLUTION_ENGINE is not set
-# CONFIG_SH_7300_SOLUTION_ENGINE is not set
-# CONFIG_SH_73180_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-CONFIG_SH_CQREEK=y
-# CONFIG_SH_DMIDA is not set
-# CONFIG_SH_EC3104 is not set
-# CONFIG_SH_SATURN is not set
-# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
-# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
-# CONFIG_SH_MPC1211 is not set
-# CONFIG_SH_SH03 is not set
-# CONFIG_SH_SECUREEDGE5410 is not set
-# CONFIG_SH_HS7751RVOIP is not set
-# CONFIG_SH_RTS7751R2D is not set
-# CONFIG_SH_EDOSK7705 is not set
-# CONFIG_SH_SH4202_MICRODEV is not set
-# CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-CONFIG_CPU_SH3=y
-# CONFIG_CPU_SH4 is not set
-# CONFIG_CPU_SUBTYPE_SH7604 is not set
-# CONFIG_CPU_SUBTYPE_SH7300 is not set
-# CONFIG_CPU_SUBTYPE_SH7705 is not set
-# CONFIG_CPU_SUBTYPE_SH7707 is not set
-CONFIG_CPU_SUBTYPE_SH7708=y
-# CONFIG_CPU_SUBTYPE_SH7709 is not set
-# CONFIG_CPU_SUBTYPE_SH7750 is not set
-# CONFIG_CPU_SUBTYPE_SH7751 is not set
-# CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
-# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
-# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
-CONFIG_MMU=y
-# CONFIG_CMDLINE_BOOL is not set
-CONFIG_MEMORY_START=0x0c000000
-CONFIG_MEMORY_SIZE=0x00400000
-# CONFIG_MEMORY_OVERRIDE is not set
-CONFIG_SH_RTC=y
-CONFIG_SH_DSP=y
-CONFIG_SH_ADC=y
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_PREEMPT is not set
-# CONFIG_UBC_WAKEUP is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
-CONFIG_SH_PCLK_FREQ=1193182
-
-#
-# CPU Frequency scaling
-#
-# CONFIG_CPU_FREQ is not set
-
-#
-# DMA support
-#
-# CONFIG_SH_DMA is not set
-
-#
-# Companion Chips
-#
-# CONFIG_HD6446X_SERIES is not set
-
-#
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
-#
-# CONFIG_PCI is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# PC-card bridges
-#
-
-#
-# PCI Hotplug Support
-#
-
-#
-# Executable file formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_FLAT is not set
-# CONFIG_BINFMT_MISC is not set
-
-#
-# SH initrd options
-#
-# CONFIG_EMBEDDED_RAMDISK is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
-# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-CONFIG_IDE_SH=y
-# CONFIG_IDE_ARM is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-# CONFIG_SCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Networking support
-#
-# CONFIG_NET is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-# CONFIG_SERIAL_SH_SCI is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# Dallas's 1-wire bus
-#
-# CONFIG_W1 is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-
-#
-# Graphics support
-#
-# CONFIG_FB is not set
-
-#
-# Console display driver support
-#
-CONFIG_VGA_CONSOLE=y
-CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# InfiniBand support
-#
-# CONFIG_INFINIBAND is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-# CONFIG_PROC_KCORE is not set
-CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
-# CONFIG_TMPFS is not set
-# CONFIG_HUGETLBFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-# CONFIG_NLS is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_FRAME_POINTER is not set
-CONFIG_SH_STANDARD_BIOS=y
-# CONFIG_EARLY_PRINTK is not set
-# CONFIG_KGDB is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Hardware crypto devices
-#
-
-#
-# Library routines
-#
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC32 is not set
-# CONFIG_LIBCRC32C is not set
index 776c1909bee31c394afcb8f976a7c34a7c7bcd43..8b6b5a779de8496b709241cfe79ee00ee31cd228 100644 (file)
@@ -1,50 +1,63 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar  2 15:09:40 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 10:51:55 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -52,82 +65,158 @@ CONFIG_CC_ALIGN_JUMPS=0
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
 #
 # System type
 #
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 CONFIG_SH_DREAMCAST=y
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
+
+#
+# Processor selection
+#
 CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
 CONFIG_CPU_SUBTYPE_SH7750=y
+CONFIG_CPU_SUBTYPE_SH7091=y
+CONFIG_CPU_SUBTYPE_SH7750R=y
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
 # CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_ST40STB1 is not set
 # CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
 CONFIG_MMU=y
-CONFIG_HUGETLB_PAGE_SIZE_64K=y
-# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
-# CONFIG_CMDLINE_BOOL is not set
+CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x01000000
-CONFIG_MEMORY_SET=y
-# CONFIG_MEMORY_OVERRIDE is not set
-CONFIG_SH_FPU=y
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_PREEMPT=y
-# CONFIG_UBC_WAKEUP is not set
+CONFIG_VSYSCALL=y
+CONFIG_HUGETLB_PAGE_SIZE_64K=y
+# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_SH_WRITETHROUGH is not set
-CONFIG_SH_OCRAM=y
+# CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
 CONFIG_SH_STORE_QUEUES=y
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
 CONFIG_SH_PCLK_FREQ=49876504
 
 #
 # CPU Frequency scaling
 #
 CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
 # CONFIG_CPU_FREQ_DEBUG is not set
 CONFIG_CPU_FREQ_STAT=y
 # CONFIG_CPU_FREQ_STAT_DETAILS is not set
@@ -137,8 +226,8 @@ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
 # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
-CONFIG_CPU_FREQ_TABLE=y
-CONFIG_SH_CPU_FREQ=y
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+# CONFIG_SH_CPU_FREQ is not set
 
 #
 # DMA support
@@ -154,24 +243,41 @@ CONFIG_NR_DMA_CHANNELS=9
 # CONFIG_HD6446X_SERIES is not set
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC1,115200 panic=3"
+
+#
+# Bus options
 #
-CONFIG_MAPLE=y
 CONFIG_PCI=y
 # CONFIG_SH_PCIDMA_NONCOHERENT is not set
 CONFIG_PCI_AUTO=y
-CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
 # CONFIG_PCCARD is not set
 
-#
-# PC-card bridges
-#
-
 #
 # PCI Hotplug Support
 #
@@ -185,9 +291,92 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 
 #
-# SH initrd options
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
 #
-# CONFIG_EMBEDDED_RAMDISK is not set
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
 
 #
 # Device Drivers
@@ -199,6 +388,12 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_STANDALONE is not set
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -217,7 +412,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
@@ -226,21 +420,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=1024
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -251,7 +433,14 @@ CONFIG_IOSCHED_CFQ=y
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -261,6 +450,7 @@ CONFIG_IOSCHED_CFQ=y
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -273,70 +463,8 @@ CONFIG_IOSCHED_CFQ=y
 # CONFIG_I2O is not set
 
 #
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
+# Network device support
 #
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
@@ -348,6 +476,11 @@ CONFIG_NETDEVICES=y
 #
 # CONFIG_ARCNET is not set
 
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
 #
 # Ethernet (10 or 100Mbit)
 #
@@ -356,6 +489,7 @@ CONFIG_MII=y
 # CONFIG_STNIC is not set
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
 
@@ -398,15 +532,22 @@ CONFIG_8139TOO=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
 #
+# CONFIG_CHELSIO_T1 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
 
 #
 # Token Ring devices
@@ -428,6 +569,8 @@ CONFIG_8139TOO=y
 # CONFIG_SLIP is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -443,6 +586,7 @@ CONFIG_8139TOO=y
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -456,19 +600,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-
 #
 # Input Device Drivers
 #
@@ -478,22 +609,33 @@ CONFIG_KEYBOARD_ATKBD=y
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_KEYBOARD_MAPLE is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 # CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_MAPLE is not set
 # CONFIG_MOUSE_VSXXXAA is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
 #
 # Character devices
 #
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -505,9 +647,11 @@ CONFIG_HW_CONSOLE=y
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -528,13 +672,14 @@ CONFIG_WATCHDOG=y
 #
 # CONFIG_SOFT_WATCHDOG is not set
 CONFIG_SH_WDT=y
+# CONFIG_SH_WDT_MMAP is not set
 
 #
 # PCI-based Watchdog Cards
 #
 # CONFIG_PCIPCWATCHDOG is not set
 # CONFIG_WDTPCI is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -546,15 +691,36 @@ CONFIG_SH_WDT=y
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
 #
 # I2C support
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -564,6 +730,7 @@ CONFIG_SH_WDT=y
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -573,7 +740,13 @@ CONFIG_SH_WDT=y
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
 # CONFIG_FB_CIRRUS is not set
@@ -583,9 +756,10 @@ CONFIG_FB=y
 # CONFIG_FB_IMSTT is not set
 CONFIG_FB_PVR2=y
 # CONFIG_FB_EPSON1355 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
 # CONFIG_FB_RIVA is not set
 # CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON_OLD is not set
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_ATY is not set
@@ -601,18 +775,20 @@ CONFIG_FB_PVR2=y
 #
 # Console display driver support
 #
-# CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
 CONFIG_FONTS=y
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
 # CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
 # CONFIG_FONT_PEARL_8x8 is not set
 # CONFIG_FONT_ACORN_8x8 is not set
 # CONFIG_FONT_MINI_4x6 is not set
 # CONFIG_FONT_SUN8x16 is not set
 # CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
 
 #
 # Logo configuration
@@ -634,12 +810,13 @@ CONFIG_LOGO_SUPERH_CLUT224=y
 #
 # USB support
 #
-# CONFIG_USB is not set
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
 #
@@ -652,30 +829,65 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 #
 # CONFIG_MMC is not set
 
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
 #
 # InfiniBand support
 #
 # CONFIG_INFINIBAND is not set
 
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
 #
 # File systems
 #
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
-CONFIG_ROMFS_FS=y
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
+# CONFIG_DNOTIFY is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -695,16 +907,14 @@ CONFIG_DNOTIFY=y
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -716,7 +926,7 @@ CONFIG_RAMFS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-CONFIG_CRAMFS=y
+# CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
@@ -726,22 +936,14 @@ CONFIG_CRAMFS=y
 #
 # Network File Systems
 #
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
 
 #
 # Partition Types
@@ -758,14 +960,19 @@ CONFIG_MSDOS_PARTITION=y
 # Profiling support
 #
 CONFIG_PROFILING=y
-CONFIG_OPROFILE=y
+# CONFIG_OPROFILE is not set
 
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_PREEMPT=y
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_KGDB is not set
@@ -781,14 +988,11 @@ CONFIG_DEBUG_PREEMPT=y
 #
 # CONFIG_CRYPTO is not set
 
-#
-# Hardware crypto devices
-#
-
 #
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
index b36f102cec81685a3178be6775653ef4c7a036b2..b931d9b2d5798158206b4011efaa1dd11eeed9f9 100644 (file)
@@ -1,21 +1,21 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-sh
-# Wed Jan  4 15:32:56 2006
+# Linux kernel version: 2.6.18
+# Tue Oct  3 11:10:06 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-# CONFIG_CLEAN_COMPILE is not set
-CONFIG_BROKEN=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 
@@ -27,26 +27,31 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
-CONFIG_HOTPLUG=y
+# CONFIG_UTS_NS is not set
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -56,7 +61,10 @@ CONFIG_BASE_SMALL=0
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
 
 #
 # IO Schedulers
@@ -77,29 +85,26 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
 CONFIG_SH_HP6XX=y
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
 # CONFIG_SH_LANDISK is not set
 # CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
 
 #
@@ -117,9 +122,11 @@ CONFIG_CPU_SH3=y
 #
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 CONFIG_CPU_SUBTYPE_SH7709=y
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
 
 #
 # SH-4 Processor Support
@@ -142,14 +149,23 @@ CONFIG_CPU_SUBTYPE_SH7709=y
 #
 # SH-4A Processor Support
 #
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
 #
 # Memory management options
 #
 CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x0c000000
+CONFIG_MEMORY_SIZE=0x00400000
+CONFIG_VSYSCALL=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -158,6 +174,7 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
 
 #
 # Cache configuration
@@ -165,22 +182,22 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_SH_WRITETHROUGH is not set
 # CONFIG_SH_OCRAM is not set
-CONFIG_MEMORY_START=0x0c000000
-CONFIG_MEMORY_SIZE=0x00400000
 
 #
 # Processor features
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_SH_RTC=y
+# CONFIG_SH_FPU_EMU is not set
 # CONFIG_SH_DSP is not set
 CONFIG_SH_ADC=y
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_PINT_IRQ=y
+CONFIG_CPU_HAS_SR_RB=y
 
 #
 # Timer support
 #
 CONFIG_SH_TMU=y
-CONFIG_SH_PCLK_FREQ_BOOL=y
 CONFIG_SH_PCLK_FREQ=22110000
 
 #
@@ -194,7 +211,6 @@ CONFIG_SH_PCLK_FREQ=22110000
 CONFIG_SH_DMA=y
 CONFIG_NR_ONCHIP_DMA_CHANNELS=4
 # CONFIG_NR_DMA_CHANNELS_BOOL is not set
-# CONFIG_DMA_PAGE_OPS is not set
 
 #
 # Companion Chips
@@ -209,9 +225,15 @@ CONFIG_HD64461_ENABLER=y
 #
 # Kernel features
 #
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
 # CONFIG_KEXEC is not set
-# CONFIG_PREEMPT is not set
 # CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
 
 #
 # Boot options
@@ -241,8 +263,6 @@ CONFIG_PCMCIA_IOCTL=y
 #
 # CONFIG_I82365 is not set
 # CONFIG_TCIC is not set
-CONFIG_HD64461_PCMCIA=y
-CONFIG_HD64461_PCMCIA_SOCKETS=1
 CONFIG_PCMCIA_PROBE=y
 
 #
@@ -256,6 +276,15 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_FLAT is not set
 # CONFIG_BINFMT_MISC is not set
 
+#
+# Power management options (EXPERIMENTAL)
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+CONFIG_APM=y
+
 #
 # Networking
 #
@@ -271,6 +300,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_STANDALONE is not set
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
 
 #
 # Connector - unified userspace <-> kernelspace linker
@@ -299,6 +329,7 @@ CONFIG_FW_LOADER=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 
@@ -315,7 +346,7 @@ CONFIG_BLK_DEV_IDE=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_BLK_DEV_IDECS=y
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -325,7 +356,6 @@ CONFIG_BLK_DEV_IDEDISK=y
 # IDE chipset support/bugfixes
 #
 CONFIG_IDE_GENERIC=y
-CONFIG_IDE_SH=y
 # CONFIG_IDE_ARM is not set
 # CONFIG_IDE_CHIPSETS is not set
 # CONFIG_BLK_DEV_IDEDMA is not set
@@ -337,6 +367,12 @@ CONFIG_IDE_SH=y
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Old CD-ROM drivers (not SCSI, not IDE)
@@ -356,18 +392,11 @@ CONFIG_IDE_SH=y
 #
 # IEEE 1394 (FireWire) support
 #
-# CONFIG_IEEE1394 is not set
 
 #
 # I2O device support
 #
 
-#
-# Network device support
-#
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
 #
 # ISDN subsystem
 #
@@ -381,6 +410,7 @@ CONFIG_IDE_SH=y
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -390,17 +420,33 @@ CONFIG_INPUT_MOUSEDEV_PSAUX=y
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_TSDEV=y
+CONFIG_INPUT_TSDEV_SCREEN_X=240
+CONFIG_INPUT_TSDEV_SCREEN_Y=320
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
 #
 # Input Device Drivers
 #
-# CONFIG_INPUT_KEYBOARD is not set
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+CONFIG_TOUCHSCREEN_HP600=y
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
 # CONFIG_INPUT_MISC is not set
 
 #
@@ -409,6 +455,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 CONFIG_SERIO=y
 # CONFIG_SERIO_I8042 is not set
 # CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_LIBPS2 is not set
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
 
@@ -418,6 +465,7 @@ CONFIG_SERIO=y
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -442,7 +490,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -470,30 +518,35 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
 #
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
 #
 
-#
-# Multimedia Capabilities Port drivers
-#
-
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -502,11 +555,13 @@ CONFIG_HWMON=y
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 CONFIG_FB=y
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
 # CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
 # CONFIG_FB_EPSON1355 is not set
@@ -553,7 +608,7 @@ CONFIG_SOUND=y
 # Open Sound System
 #
 CONFIG_SOUND_PRIME=y
-# CONFIG_OBSOLETE_OSS_DRIVER is not set
+# CONFIG_OSS_OBSOLETE_DRIVER is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
 CONFIG_SOUND_SH_DAC_AUDIO=y
@@ -564,6 +619,7 @@ CONFIG_SOUND_SH_DAC_AUDIO_CHANNEL=1
 #
 # CONFIG_USB_ARCH_HAS_HCD is not set
 # CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -579,13 +635,43 @@ CONFIG_SOUND_SH_DAC_AUDIO_CHANNEL=1
 #
 # CONFIG_MMC is not set
 
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
 #
 # InfiniBand support
 #
-# CONFIG_INFINIBAND is not set
 
 #
-# SN Devices
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
 #
 
 #
@@ -595,7 +681,6 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -603,6 +688,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
@@ -630,12 +716,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -713,9 +800,14 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_FRAME_POINTER is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_UNWIND_INFO is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_KGDB is not set
 
@@ -730,10 +822,6 @@ CONFIG_LOG_BUF_SHIFT=14
 #
 # CONFIG_CRYPTO is not set
 
-#
-# Hardware crypto devices
-#
-
 #
 # Library routines
 #
@@ -741,3 +829,4 @@ CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
similarity index 53%
rename from arch/mips/configs/it8172_defconfig
rename to arch/sh/configs/hs7751rvoip_defconfig
index 37f9dd7187b1073d12ba0a0ffda7597cfc6372ea..e1a886d621dbd8fe7d34a0295b645dabb9a8b37d 100644 (file)
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:11 2006
-#
-CONFIG_MIPS=y
-
-#
-# Machine selection
-#
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_PB1200 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_DB1200 is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
-# CONFIG_MIPS_COBALT is not set
-# CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-CONFIG_MIPS_ITE8172=y
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
-# CONFIG_MIPS_ATLAS is not set
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_MIPS_SEAD is not set
-# CONFIG_WR_PPMC is not set
-# CONFIG_MIPS_SIM is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
-# CONFIG_PNX8550_JBS is not set
-# CONFIG_DDB5477 is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_PMC_YOSEMITE is not set
-# CONFIG_QEMU is not set
-# CONFIG_MARKEINS is not set
-# CONFIG_SGI_IP22 is not set
-# CONFIG_SGI_IP27 is not set
-# CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_BIGSUR is not set
-# CONFIG_SIBYTE_SWARM is not set
-# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_PTSWARM is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
-# CONFIG_SIBYTE_CRHINE is not set
-# CONFIG_SIBYTE_CRHONE is not set
-# CONFIG_SNI_RM200_PCI is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_TOSHIBA_RBTX4938 is not set
-# CONFIG_IT8172_REVC is not set
+# Linux kernel version: 2.6.18
+# Tue Oct  3 13:04:52 2006
+#
+CONFIG_SUPERH=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_NEED_PCI_MAP_STATE=y
-# CONFIG_CPU_BIG_ENDIAN is not set
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_ITE_BOARD_GEN=y
-CONFIG_IT8172_CIR=y
-CONFIG_IT8712=y
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-
-#
-# CPU selection
-#
-# CONFIG_CPU_MIPS32_R1 is not set
-# CONFIG_CPU_MIPS32_R2 is not set
-# CONFIG_CPU_MIPS64_R1 is not set
-# CONFIG_CPU_MIPS64_R2 is not set
-# CONFIG_CPU_R3000 is not set
-# CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_VR41XX is not set
-# CONFIG_CPU_R4300 is not set
-# CONFIG_CPU_R4X00 is not set
-# CONFIG_CPU_TX49XX is not set
-# CONFIG_CPU_R5000 is not set
-# CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_R6000 is not set
-CONFIG_CPU_NEVADA=y
-# CONFIG_CPU_R8000 is not set
-# CONFIG_CPU_R10000 is not set
-# CONFIG_CPU_RM7000 is not set
-# CONFIG_CPU_RM9000 is not set
-# CONFIG_CPU_SB1 is not set
-CONFIG_SYS_HAS_CPU_R5432=y
-CONFIG_SYS_HAS_CPU_NEVADA=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
-
-#
-# Kernel type
-#
-CONFIG_32BIT=y
-# CONFIG_64BIT is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_8KB is not set
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
-CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
-# CONFIG_MIPS_MT_SMP is not set
-# CONFIG_MIPS_VPE_LOADER is not set
-CONFIG_CPU_HAS_LLSC=y
-CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_ARCH_FLATMEM_ENABLE=y
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
-# CONFIG_HZ_48 is not set
-# CONFIG_HZ_100 is not set
-# CONFIG_HZ_128 is not set
-# CONFIG_HZ_250 is not set
-# CONFIG_HZ_256 is not set
-CONFIG_HZ_1000=y
-# CONFIG_HZ_1024 is not set
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=1000
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -154,6 +17,7 @@ CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
@@ -163,29 +27,33 @@ CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_IPC_NS is not set
+CONFIG_POSIX_MQUEUE=y
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
-CONFIG_RELAY=y
+# CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_HOTPLUG is not set
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -196,13 +64,14 @@ CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -221,11 +90,172 @@ CONFIG_DEFAULT_AS=y
 CONFIG_DEFAULT_IOSCHED="anticipatory"
 
 #
-# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+# System type
+#
+# CONFIG_SH_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SOLUTION_ENGINE is not set
+# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
+# CONFIG_SH_73180_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SYSTEMH is not set
+# CONFIG_SH_HP6XX is not set
+# CONFIG_SH_EC3104 is not set
+# CONFIG_SH_SATURN is not set
+# CONFIG_SH_DREAMCAST is not set
+# CONFIG_SH_BIGSUR is not set
+# CONFIG_SH_MPC1211 is not set
+# CONFIG_SH_SH03 is not set
+# CONFIG_SH_SECUREEDGE5410 is not set
+CONFIG_SH_HS7751RVOIP=y
+# CONFIG_SH_7710VOIPGW is not set
+# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
+# CONFIG_SH_EDOSK7705 is not set
+# CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
+# CONFIG_SH_UNKNOWN is not set
+
+#
+# Processor selection
+#
+CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7300 is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+CONFIG_CPU_SUBTYPE_SH7751=y
+CONFIG_CPU_SUBTYPE_SH7751R=y
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
+# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
 #
-CONFIG_HW_HAS_PCI=y
-# CONFIG_PCI is not set
 CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x0c000000
+CONFIG_MEMORY_SIZE=0x04000000
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
+# CONFIG_SH_WRITETHROUGH is not set
+# CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
+# CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
+
+#
+# HS7751RVoIP options
+#
+CONFIG_HS7751RVOIP_CODEC=y
+CONFIG_SH_PCLK_FREQ=60000000
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+# CONFIG_HD6446X_SERIES is not set
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="mem=64M console=ttySC1,115200 root=/dev/hda1"
+
+#
+# Bus options
+#
+# CONFIG_PCI is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -240,8 +270,13 @@ CONFIG_MMU=y
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_FLAT is not set
 # CONFIG_BINFMT_MISC is not set
-CONFIG_TRAD_SIGNALS=y
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
 
 #
 # Networking
@@ -256,18 +291,22 @@ CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-CONFIG_NET_KEY=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_NET_KEY is not set
 CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
 CONFIG_IP_FIB_HASH=y
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+# CONFIG_IP_PNP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
 # CONFIG_ARPD is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_INET_AH is not set
@@ -275,16 +314,17 @@ CONFIG_IP_PNP_BOOTP=y
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
-CONFIG_NETWORK_SECMARK=y
+# CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 
 #
@@ -310,7 +350,6 @@ CONFIG_NETWORK_SECMARK=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -326,13 +365,7 @@ CONFIG_NETWORK_SECMARK=y
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-CONFIG_IEEE80211=m
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=m
-CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_SOFTMAC=m
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
-CONFIG_WIRELESS_EXT=y
+# CONFIG_IEEE80211 is not set
 
 #
 # Device Drivers
@@ -343,93 +376,18 @@ CONFIG_WIRELESS_EXT=y
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
 # CONFIG_SYS_HYPERVISOR is not set
 
 #
 # Connector - unified userspace <-> kernelspace linker
 #
-CONFIG_CONNECTOR=m
+# CONFIG_CONNECTOR is not set
 
 #
 # Memory Technology Devices (MTD)
 #
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_PARTITIONS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-# CONFIG_MTD_BLOCK is not set
-# CONFIG_MTD_BLOCK_RO is not set
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-# CONFIG_RFD_FTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=y
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x8000000
-CONFIG_MTD_PHYSMAP_LEN=0x2000000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
-# CONFIG_MTD_PLATRAM is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLOCK2MTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# OneNAND Flash Device Drivers
-#
-# CONFIG_MTD_ONENAND is not set
+# CONFIG_MTD is not set
 
 #
 # Parallel port support
@@ -444,20 +402,18 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
 # Block devices
 #
 # CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-CONFIG_ATA_OVER_ETH=m
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
 
 #
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=1
 CONFIG_BLK_DEV_IDE=y
 
 #
@@ -483,8 +439,14 @@ CONFIG_IDE_GENERIC=y
 #
 # SCSI device support
 #
-CONFIG_RAID_ATTRS=m
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -516,25 +478,15 @@ CONFIG_NETDEVICES=y
 #
 # PHY device support
 #
-CONFIG_PHYLIB=m
-
-#
-# MII PHY device drivers
-#
-CONFIG_MARVELL_PHY=m
-CONFIG_DAVICOM_PHY=m
-CONFIG_QSEMI_PHY=m
-CONFIG_LXT_PHY=m
-CONFIG_CICADA_PHY=m
-CONFIG_VITESSE_PHY=m
-CONFIG_SMSC_PHY=m
+# CONFIG_PHYLIB is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
-# CONFIG_DM9000 is not set
+CONFIG_MII=y
+# CONFIG_STNIC is not set
+# CONFIG_SMC91X is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -578,14 +530,12 @@ CONFIG_NET_ETHERNET=y
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
 #
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_JOYDEV is not set
 # CONFIG_INPUT_TSDEV is not set
 # CONFIG_INPUT_EVDEV is not set
@@ -604,42 +554,33 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # Hardware I/O ports
 #
 CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_I8042=y
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=m
+# CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
 
 #
 # Character devices
 #
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_VT is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_QTRONIX_KEYBOARD is not set
-# CONFIG_IT8172_SCR0 is not set
-# CONFIG_IT8172_SCR1 is not set
-# CONFIG_ITE_GPIO is not set
 
 #
 # Serial drivers
 #
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250 is not set
 
 #
 # Non-8250 serial port support
 #
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_LEGACY_PTYS is not set
 
 #
 # IPMI
@@ -650,8 +591,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -681,13 +621,16 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
 #
-# CONFIG_HWMON is not set
+CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -707,32 +650,14 @@ CONFIG_VIDEO_V4L2=y
 #
 # Graphics support
 #
-# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
 #
-CONFIG_SOUND=y
-
-#
-# Advanced Linux Sound Architecture
-#
-# CONFIG_SND is not set
-
-#
-# Open Sound System
-#
-CONFIG_SOUND_PRIME=y
-CONFIG_SOUND_IT8172=y
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND is not set
 
 #
 # USB support
@@ -814,7 +739,7 @@ CONFIG_INOTIFY_USER=y
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
-CONFIG_FUSE_FS=m
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -834,8 +759,11 @@ CONFIG_FUSE_FS=m
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
@@ -850,8 +778,6 @@ CONFIG_RAMFS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-# CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_HPFS_FS is not set
@@ -863,19 +789,20 @@ CONFIG_RAMFS=y
 # Network File Systems
 #
 CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+CONFIG_NFS_DIRECTIO=y
 # CONFIG_NFSD is not set
-CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -884,8 +811,23 @@ CONFIG_SUNRPC=y
 #
 # Partition Types
 #
-# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
 CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
 
 #
 # Native Language Support
@@ -901,48 +843,55 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_DEBUG_FS is not set
-CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_KGDB is not set
 
 #
 # Security options
 #
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 
 #
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_MANAGER=m
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -953,9 +902,7 @@ CONFIG_CRYPTO_CRC32C=m
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
-CONFIG_CRC16=m
-CONFIG_CRC32=m
-CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=m
-CONFIG_ZLIB_DEFLATE=m
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
 CONFIG_PLIST=y
index 6b43316d03cfa18b6c9d5056af876ca835700e0f..238c0f109907533b8e6ccfef7b124048aeddac4e 100644 (file)
@@ -1,21 +1,21 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-sh
-# Sun Sep 11 13:00:46 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 11:14:13 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 
@@ -26,29 +26,36 @@ CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_EMBEDDED is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -56,40 +63,57 @@ CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
 #
 # System type
 #
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
 # CONFIG_SH_HP6XX is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
 CONFIG_SH_LANDISK=y
 # CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
 
 #
@@ -107,9 +131,11 @@ CONFIG_CPU_SH4=y
 #
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
 
 #
 # SH-4 Processor Support
@@ -132,14 +158,23 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
 #
 # SH-4A Processor Support
 #
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
 #
 # Memory management options
 #
 CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x0c000000
+CONFIG_MEMORY_SIZE=0x04000000
+CONFIG_VSYSCALL=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -147,6 +182,8 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
 
 #
 # Cache configuration
@@ -154,21 +191,21 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_SH_WRITETHROUGH is not set
 # CONFIG_SH_OCRAM is not set
-CONFIG_MEMORY_START=0x0c000000
-CONFIG_MEMORY_SIZE=0x04000000
 
 #
 # Processor features
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
 # CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
 
 #
 # Timer support
 #
 CONFIG_SH_TMU=y
-CONFIG_SH_PCLK_FREQ_BOOL=y
 CONFIG_SH_PCLK_FREQ=33333333
 
 #
@@ -192,9 +229,15 @@ CONFIG_HEARTBEAT=y
 #
 # Kernel features
 #
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
 CONFIG_KEXEC=y
-# CONFIG_PREEMPT is not set
 # CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
 
 #
 # Boot options
@@ -212,7 +255,7 @@ CONFIG_PCI=y
 CONFIG_SH_PCIDMA_NONCOHERENT=y
 CONFIG_PCI_AUTO=y
 CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -228,6 +271,11 @@ CONFIG_CARDBUS=y
 # PC-card bridges
 #
 CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
 # CONFIG_PD6729 is not set
 # CONFIG_I82092 is not set
 # CONFIG_I82365 is not set
@@ -247,6 +295,11 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_FLAT is not set
 # CONFIG_BINFMT_MISC is not set
 
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
 #
 # Networking
 #
@@ -255,9 +308,13 @@ CONFIG_NET=y
 #
 # Networking options
 #
+# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -279,20 +336,32 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 
 #
 # IP: Virtual Server Configuration
 #
 # CONFIG_IP_VS is not set
 # CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
 # CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NETFILTER_XTABLES is not set
 
 #
 # IP: Netfilter Configuration
@@ -308,66 +377,9 @@ CONFIG_IP_NF_IRC=m
 CONFIG_IP_NF_TFTP=m
 CONFIG_IP_NF_AMANDA=m
 # CONFIG_IP_NF_PPTP is not set
+# CONFIG_IP_NF_H323 is not set
+# CONFIG_IP_NF_SIP is not set
 CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-CONFIG_IP_NF_MATCH_RECENT=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
-CONFIG_IP_NF_MATCH_OWNER=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_REALM=m
-CONFIG_IP_NF_MATCH_SCTP=m
-# CONFIG_IP_NF_MATCH_DCCP is not set
-CONFIG_IP_NF_MATCH_COMMENT=m
-CONFIG_IP_NF_MATCH_CONNMARK=m
-# CONFIG_IP_NF_MATCH_CONNBYTES is not set
-CONFIG_IP_NF_MATCH_HASHLIMIT=m
-# CONFIG_IP_NF_MATCH_STRING is not set
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-# CONFIG_IP_NF_TARGET_NFQUEUE is not set
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_TARGET_NETMAP=m
-CONFIG_IP_NF_TARGET_SAME=m
-# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_CLASSIFY=m
-# CONFIG_IP_NF_TARGET_TTL is not set
-CONFIG_IP_NF_TARGET_CONNMARK=m
-# CONFIG_IP_NF_TARGET_CLUSTERIP is not set
-CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_TARGET_NOTRACK=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
 
 #
 # DCCP Configuration (EXPERIMENTAL)
@@ -378,6 +390,11 @@ CONFIG_IP_NF_ARP_MANGLE=m
 # SCTP Configuration (EXPERIMENTAL)
 #
 # CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_VLAN_8021Q is not set
@@ -389,11 +406,13 @@ CONFIG_ATALK=m
 # CONFIG_DEV_APPLETALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
 # CONFIG_NET_SCHED is not set
-CONFIG_NET_CLS_ROUTE=y
 
 #
 # Network testing
@@ -414,6 +433,7 @@ CONFIG_NET_CLS_ROUTE=y
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
 
 #
 # Connector - unified userspace <-> kernelspace linker
@@ -451,17 +471,9 @@ CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_BLK_DEV_INITRD is not set
-# CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -518,7 +530,6 @@ CONFIG_BLK_DEV_AEC62XX=y
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
-CONFIG_IDE_SH=y
 # CONFIG_IDE_ARM is not set
 # CONFIG_IDE_CHIPSETS is not set
 CONFIG_BLK_DEV_IDEDMA=y
@@ -531,6 +542,7 @@ CONFIG_IDEDMA_AUTO=y
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -551,16 +563,18 @@ CONFIG_SCSI_MULTI_LUN=y
 # CONFIG_SCSI_LOGGING is not set
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
 # CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
 #
+# CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
@@ -569,12 +583,14 @@ CONFIG_SCSI_MULTI_LUN=y
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_DTC3280 is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -584,20 +600,14 @@ CONFIG_SCSI_MULTI_LUN=y
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PSI240I is not set
 # CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_QLA_FC is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_SYM53C416 is not set
 # CONFIG_SCSI_DC395x is not set
@@ -615,6 +625,11 @@ CONFIG_SCSI_QLA2XXX=y
 # CONFIG_PCMCIA_QLOGIC is not set
 # CONFIG_PCMCIA_SYM53C500 is not set
 
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
 #
 # Old CD-ROM drivers (not SCSI, not IDE)
 #
@@ -629,8 +644,7 @@ CONFIG_MD_LINEAR=m
 CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_RAID6 is not set
+# CONFIG_MD_RAID456 is not set
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 # CONFIG_BLK_DEV_DM is not set
@@ -694,7 +708,6 @@ CONFIG_MII=y
 # CONFIG_DEPCA is not set
 # CONFIG_HP100 is not set
 # CONFIG_NET_ISA is not set
-# CONFIG_NE2000 is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
@@ -730,10 +743,12 @@ CONFIG_8139CP=y
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -741,6 +756,7 @@ CONFIG_8139CP=y
 # CONFIG_CHELSIO_T1 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
 
 #
 # Token Ring devices
@@ -785,6 +801,7 @@ CONFIG_8139CP=y
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -819,6 +836,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -830,6 +848,7 @@ CONFIG_HW_CONSOLE=y
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -847,8 +866,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
-CONFIG_RS5C313_RTC=y
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -863,57 +881,84 @@ CONFIG_RS5C313_RTC=y
 # PCMCIA character devices
 #
 # CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
 # CONFIG_RAW_DRIVER is not set
 
 #
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
 #
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
 #
 
-#
-# Multimedia Capabilities Port drivers
-#
-
 #
 # Multimedia devices
 #
 CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
 
 #
-# Video For Linux
+# Video Capture Adapters
 #
 
 #
-# Video Adapters
+# Video Capture Adapters
 #
+# CONFIG_VIDEO_ADV_DEBUG is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+# CONFIG_VIDEO_VIVI is not set
 # CONFIG_VIDEO_PMS is not set
 # CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
 # CONFIG_VIDEO_STRADIS is not set
-# CONFIG_VIDEO_MXB is not set
-# CONFIG_VIDEO_DPC is not set
-# CONFIG_VIDEO_HEXIUM_ORION is not set
-# CONFIG_VIDEO_HEXIUM_GEMINI is not set
+
+#
+# V4L USB devices
+#
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+# CONFIG_USB_QUICKCAM_MESSENGER is not set
+# CONFIG_USB_ET61X251 is not set
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+# CONFIG_USB_ZC0301 is not set
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
 
 #
 # Radio Adapters
@@ -932,15 +977,18 @@ CONFIG_VIDEO_DEV=m
 # CONFIG_RADIO_TRUST is not set
 # CONFIG_RADIO_TYPHOON is not set
 # CONFIG_RADIO_ZOLTRIX is not set
+CONFIG_USB_DSBR=m
 
 #
 # Digital Video Broadcasting Devices
 #
 # CONFIG_DVB is not set
+CONFIG_USB_DABUSB=m
 
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
 
 #
@@ -949,6 +997,7 @@ CONFIG_VIDEO_DEV=m
 # CONFIG_MDA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FONT_8x16=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -964,32 +1013,21 @@ CONFIG_SOUND=m
 # Open Sound System
 #
 CONFIG_SOUND_PRIME=m
+# CONFIG_OSS_OBSOLETE_DRIVER is not set
 # CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
 # CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
 # CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_SONICVIBES is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
 # CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_SOUND_ALI5455 is not set
-# CONFIG_SOUND_FORTE is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_AD1980 is not set
 
 #
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
@@ -1007,6 +1045,7 @@ CONFIG_USB_DEVICEFS=y
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN is not set
@@ -1017,15 +1056,15 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 #
 # USB Device Class drivers
 #
-CONFIG_OBSOLETE_OSS_USB_DRIVER=y
-CONFIG_USB_AUDIO=m
-# CONFIG_USB_BLUETOOTH_TTY is not set
-CONFIG_USB_MIDI=m
 # CONFIG_USB_ACM is not set
 CONFIG_USB_PRINTER=m
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
 #
 CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -1037,12 +1076,16 @@ CONFIG_USB_STORAGE_DPCM=y
 CONFIG_USB_STORAGE_SDDR09=y
 CONFIG_USB_STORAGE_SDDR55=y
 CONFIG_USB_STORAGE_JUMPSHOT=y
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
 
 #
 # USB Input Devices
 #
 CONFIG_USB_HID=m
 CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
 # CONFIG_HID_FF is not set
 # CONFIG_USB_HIDDEV is not set
 
@@ -1056,14 +1099,14 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_ACECAD is not set
 # CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_ITMTOUCH is not set
-# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_TOUCHSCREEN is not set
 # CONFIG_USB_YEALINK is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 
 #
 # USB Imaging devices
@@ -1071,20 +1114,6 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
 
-#
-# USB Multimedia devices
-#
-CONFIG_USB_DABUSB=m
-CONFIG_USB_VICAM=m
-CONFIG_USB_DSBR=m
-CONFIG_USB_IBMCAM=m
-CONFIG_USB_KONICAWC=m
-CONFIG_USB_OV511=m
-CONFIG_USB_SE401=m
-CONFIG_USB_SN9C102=m
-CONFIG_USB_STV680=m
-CONFIG_USB_PWC=m
-
 #
 # USB Network Adapters
 #
@@ -1104,7 +1133,9 @@ CONFIG_USB_MON=y
 #
 CONFIG_USB_SERIAL=m
 # CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_AIRCABLE is not set
 # CONFIG_USB_SERIAL_AIRPRIME is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
 # CONFIG_USB_SERIAL_BELKIN is not set
 # CONFIG_USB_SERIAL_WHITEHEAT is not set
 # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
@@ -1112,6 +1143,7 @@ CONFIG_USB_SERIAL=m
 # CONFIG_USB_SERIAL_CYPRESS_M8 is not set
 # CONFIG_USB_SERIAL_EMPEG is not set
 CONFIG_USB_SERIAL_FTDI_SIO=m
+# CONFIG_USB_SERIAL_FUNSOFT is not set
 # CONFIG_USB_SERIAL_VISOR is not set
 # CONFIG_USB_SERIAL_IPAQ is not set
 # CONFIG_USB_SERIAL_IR is not set
@@ -1124,9 +1156,12 @@ CONFIG_USB_SERIAL_FTDI_SIO=m
 # CONFIG_USB_SERIAL_KLSI is not set
 # CONFIG_USB_SERIAL_KOBIL_SCT is not set
 # CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
 CONFIG_USB_SERIAL_PL2303=m
 # CONFIG_USB_SERIAL_HP4X is not set
 # CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
 # CONFIG_USB_SERIAL_TI is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
@@ -1138,15 +1173,18 @@ CONFIG_USB_SERIAL_PL2303=m
 #
 CONFIG_USB_EMI62=m
 CONFIG_USB_EMI26=m
+# CONFIG_USB_ADUTUX is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
 # CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
 CONFIG_USB_SISUSBVGA=m
 CONFIG_USB_SISUSBVGA_CON=y
 # CONFIG_USB_LD is not set
@@ -1166,13 +1204,44 @@ CONFIG_USB_SISUSBVGA_CON=y
 #
 # CONFIG_MMC is not set
 
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
 #
 # InfiniBand support
 #
 # CONFIG_INFINIBAND is not set
 
 #
-# SN Devices
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
 #
 
 #
@@ -1195,9 +1264,11 @@ CONFIG_REISERFS_FS=y
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=y
 CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
@@ -1229,12 +1300,14 @@ CONFIG_NTFS_RW=y
 #
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -1252,7 +1325,8 @@ CONFIG_RAMFS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_SYSV_FS is not set
 CONFIG_UFS_FS=m
-CONFIG_UFS_FS_WRITE=y
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
 
 #
 # Network File Systems
@@ -1341,9 +1415,13 @@ CONFIG_NLS_CODEPAGE_932=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_FRAME_POINTER is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
 CONFIG_SH_STANDARD_BIOS=y
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_EARLY_PRINTK is not set
@@ -1360,10 +1438,6 @@ CONFIG_SH_STANDARD_BIOS=y
 #
 # CONFIG_CRYPTO is not set
 
-#
-# Hardware crypto devices
-#
-
 #
 # Library routines
 #
@@ -1371,3 +1445,6 @@ CONFIG_SH_STANDARD_BIOS=y
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_PLIST=y
index ab3db76d1e51b5d4d6c92bf87c1ab8337889f003..e89d951c3c16b6ad327eb4b72a6c0c1279a1c2c4 100644 (file)
@@ -1,19 +1,21 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc1
-# Fri Jan 27 19:43:20 2006
+# Linux kernel version: 2.6.18
+# Tue Oct  3 11:27:01 2006
 #
 CONFIG_SUPERH=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
@@ -28,13 +30,17 @@ CONFIG_SWAP=y
 # CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -45,11 +51,9 @@ CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
 CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -62,7 +66,10 @@ CONFIG_BASE_SMALL=0
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
 
 #
 # IO Schedulers
@@ -83,30 +90,26 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
 # CONFIG_SH_HP6XX is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
 # CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 CONFIG_SH_SH4202_MICRODEV=y
 # CONFIG_SH_LANDISK is not set
 # CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
 
 #
@@ -124,9 +127,11 @@ CONFIG_CPU_SH4=y
 #
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
 
 #
 # SH-4 Processor Support
@@ -149,14 +154,25 @@ CONFIG_CPU_SUBTYPE_SH4_202=y
 #
 # SH-4A Processor Support
 #
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
 #
 # Memory management options
 #
 CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x04000000
+CONFIG_VSYSCALL=y
+CONFIG_HUGETLB_PAGE_SIZE_64K=y
+# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -165,22 +181,21 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
 
 #
 # Cache configuration
 #
 # CONFIG_SH_DIRECT_MAPPED is not set
-# CONFIG_SH_WRITETHROUGH is not set
+CONFIG_SH_WRITETHROUGH=y
 # CONFIG_SH_OCRAM is not set
-CONFIG_MEMORY_START=0x08000000
-CONFIG_MEMORY_SIZE=0x04000000
 
 #
 # Processor features
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_SH_RTC=y
 CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
 # CONFIG_SH_STORE_QUEUES is not set
 CONFIG_CPU_HAS_INTEVT=y
 CONFIG_CPU_HAS_SR_RB=y
@@ -212,9 +227,16 @@ CONFIG_HEARTBEAT=y
 #
 # Kernel features
 #
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
 # CONFIG_KEXEC is not set
-CONFIG_PREEMPT=y
 # CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
 
 #
 # Boot options
@@ -223,12 +245,12 @@ CONFIG_ZERO_PAGE_OFFSET=0x00001000
 CONFIG_BOOT_LINK_OFFSET=0x00800000
 # CONFIG_UBC_WAKEUP is not set
 CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttySC0,115200"
+CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/hda1"
 
 #
 # Bus options
 #
-# CONFIG_SUPERHYWAY is not set
+CONFIG_SUPERHYWAY=y
 # CONFIG_PCI is not set
 
 #
@@ -247,6 +269,11 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_FLAT is not set
 # CONFIG_BINFMT_MISC is not set
 
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
 #
 # Networking
 #
@@ -255,15 +282,19 @@ CONFIG_NET=y
 #
 # Networking options
 #
+# CONFIG_NETDEBUG is not set
 # CONFIG_PACKET is not set
 # CONFIG_UNIX is not set
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_FIB_HASH=y
 CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_DHCP is not set
 # CONFIG_IP_PNP_BOOTP is not set
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
@@ -273,12 +304,19 @@ CONFIG_IP_PNP_DHCP=y
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 
 #
@@ -304,7 +342,6 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -332,6 +369,7 @@ CONFIG_TCP_CONG_BIC=y
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
 
 #
 # Connector - unified userspace <-> kernelspace linker
@@ -361,6 +399,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
@@ -397,6 +436,12 @@ CONFIG_IDE_GENERIC=y
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -502,6 +547,7 @@ CONFIG_SMC91X=y
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -518,7 +564,8 @@ CONFIG_LEGACY_PTY_COUNT=256
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-CONFIG_RTC=y
+CONFIG_HW_RANDOM=y
+# CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 
@@ -547,27 +594,26 @@ CONFIG_RTC=y
 #
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
 #
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
 #
 
-#
-# Multimedia Capabilities Port drivers
-#
-
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -577,7 +623,9 @@ CONFIG_HWMON=y
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -589,6 +637,7 @@ CONFIG_HWMON=y
 #
 # CONFIG_USB_ARCH_HAS_HCD is not set
 # CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -604,16 +653,43 @@ CONFIG_HWMON=y
 #
 # CONFIG_MMC is not set
 
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
 #
 # InfiniBand support
 #
 
 #
-# SN Devices
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
 #
 
 #
-# EDAC - error detection and reporting (RAS)
+# DMA Devices
 #
 
 #
@@ -637,6 +713,7 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
@@ -664,12 +741,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
-# CONFIG_HUGETLBFS is not set
-# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -772,10 +850,14 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_FRAME_POINTER is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_UNWIND_INFO is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_KGDB is not set
@@ -790,6 +872,9 @@ CONFIG_LOG_BUF_SHIFT=14
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
@@ -799,6 +884,8 @@ CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_CBC=y
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
@@ -813,7 +900,6 @@ CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_TEST is not set
 
 #
 # Hardware crypto devices
@@ -826,3 +912,4 @@ CONFIG_CRYPTO_DES=y
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
index d597fc57154977008dba6dbac5d3ac9dd693bc4c..2470364948e75aa007d53597204194bbe6900171 100644 (file)
@@ -1,20 +1,21 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-sh
-# Sat Jan  7 19:47:53 2006
+# Linux kernel version: 2.6.18
+# Tue Oct  3 11:32:47 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
@@ -26,33 +27,38 @@ CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+# CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -60,7 +66,6 @@ CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
@@ -68,7 +73,10 @@ CONFIG_KMOD=y
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
 
 #
 # IO Schedulers
@@ -89,31 +97,26 @@ CONFIG_DEFAULT_IOSCHED="noop"
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
 # CONFIG_SH_HP6XX is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
-# CONFIG_SH_R77703DRP is not set
 CONFIG_SH_R7780RP=y
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
 # CONFIG_SH_LANDISK is not set
 # CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
 
 #
@@ -132,9 +135,11 @@ CONFIG_CPU_SH4A=y
 #
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
 
 #
 # SH-4 Processor Support
@@ -157,15 +162,24 @@ CONFIG_CPU_SH4A=y
 #
 # SH-4A Processor Support
 #
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 CONFIG_CPU_SUBTYPE_SH7780=y
 
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
 #
 # Memory management options
 #
 CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x08000000
 CONFIG_32BIT=y
+CONFIG_VSYSCALL=y
 CONFIG_HUGETLB_PAGE_SIZE_64K=y
 # CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -176,6 +190,7 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
 
 #
 # Cache configuration
@@ -183,21 +198,27 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_SH_WRITETHROUGH is not set
 # CONFIG_SH_OCRAM is not set
-CONFIG_MEMORY_START=0x08000000
-CONFIG_MEMORY_SIZE=0x08000000
 
 #
 # Processor features
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
 CONFIG_SH_STORE_QUEUES=y
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_INTC2_IRQ=y
+CONFIG_CPU_HAS_SR_RB=y
 
 #
 # Timer support
 #
 CONFIG_SH_TMU=y
-CONFIG_SH_PCLK_FREQ_BOOL=y
+
+#
+# R7780RP options
+#
+CONFIG_SH_R7780MP=y
 CONFIG_SH_PCLK_FREQ=32000000
 
 #
@@ -220,11 +241,16 @@ CONFIG_NR_ONCHIP_DMA_CHANNELS=6
 #
 # Kernel features
 #
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
 # CONFIG_KEXEC is not set
-CONFIG_PREEMPT=y
 # CONFIG_SMP is not set
-CONFIG_CPU_HAS_INTEVT=y
-CONFIG_CPU_HAS_INTC2_IRQ=y
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
 
 #
 # Boot options
@@ -242,7 +268,7 @@ CONFIG_PCI=y
 CONFIG_SH_PCIDMA_NONCOHERENT=y
 CONFIG_PCI_AUTO=y
 CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 # CONFIG_PCI_DEBUG is not set
 
 #
@@ -265,6 +291,11 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_FLAT is not set
 # CONFIG_BINFMT_MISC is not set
 
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
 #
 # Networking
 #
@@ -273,9 +304,13 @@ CONFIG_NET=y
 #
 # Networking options
 #
+# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -297,12 +332,19 @@ CONFIG_IP_PNP_DHCP=y
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 
 #
@@ -314,16 +356,21 @@ CONFIG_TCP_CONG_BIC=y
 # SCTP Configuration (EXPERIMENTAL)
 #
 # CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 CONFIG_BRIDGE=m
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
+CONFIG_LLC=m
 # CONFIG_LLC2 is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -340,6 +387,7 @@ CONFIG_BRIDGE=m
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_IEEE80211 is not set
+CONFIG_WIRELESS_EXT=y
 
 #
 # Device Drivers
@@ -352,6 +400,7 @@ CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=m
 # CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
 
 #
 # Connector - unified userspace <-> kernelspace linker
@@ -386,6 +435,7 @@ CONFIG_FW_LOADER=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
@@ -438,13 +488,11 @@ CONFIG_BLK_DEV_AEC62XX=m
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
 CONFIG_BLK_DEV_PDC202XX_NEW=m
-# CONFIG_PDC202XX_FORCE is not set
 # CONFIG_BLK_DEV_SVWKS is not set
 CONFIG_BLK_DEV_SIIMAGE=m
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
-CONFIG_IDE_SH=y
 # CONFIG_IDE_ARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
@@ -456,6 +504,7 @@ CONFIG_IDEDMA_AUTO=y
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=m
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -476,12 +525,13 @@ CONFIG_CHR_DEV_SG=m
 # CONFIG_SCSI_LOGGING is not set
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
 # CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
@@ -494,33 +544,34 @@ CONFIG_CHR_DEV_SG=m
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=m
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_QLA_FC is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
 #
 # Multi-device support (RAID and LVM)
 #
@@ -580,9 +631,9 @@ CONFIG_MII=y
 #
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
-CONFIG_NE2000=y
 CONFIG_NET_PCI=y
 CONFIG_PCNET32=m
+# CONFIG_PCNET32_NAPI is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_B44 is not set
@@ -605,6 +656,7 @@ CONFIG_8139TOO_8129=y
 # CONFIG_TLAN is not set
 CONFIG_VIA_RHINE=m
 CONFIG_VIA_RHINE_MMIO=y
+# CONFIG_VIA_RHINE_NAPI is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -613,6 +665,7 @@ CONFIG_VIA_RHINE_MMIO=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=m
 # CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -620,10 +673,12 @@ CONFIG_R8169=y
 # CONFIG_R8169_NAPI is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -631,6 +686,7 @@ CONFIG_R8169=y
 # CONFIG_CHELSIO_T1 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
 
 #
 # Token Ring devices
@@ -641,6 +697,7 @@ CONFIG_R8169=y
 # Wireless LAN (non-hamradio)
 #
 CONFIG_NET_RADIO=y
+# CONFIG_NET_WIRELESS_RTNETLINK is not set
 
 #
 # Obsolete Wireless cards support (pre-802.11)
@@ -650,6 +707,8 @@ CONFIG_NET_RADIO=y
 #
 # Wireless 802.11b ISA/PCI cards support
 #
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
 CONFIG_HERMES=m
 # CONFIG_PLX_HERMES is not set
 # CONFIG_TMD_HERMES is not set
@@ -692,6 +751,7 @@ CONFIG_NET_WIRELESS=y
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -714,6 +774,7 @@ CONFIG_KEYBOARD_ATKBD=y
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
@@ -745,6 +806,7 @@ CONFIG_SERIO_LIBPS2=y
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -762,7 +824,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -785,30 +847,35 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
 #
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
 #
 
-#
-# Multimedia Capabilities Port drivers
-#
-
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -818,7 +885,9 @@ CONFIG_HWMON=y
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -834,18 +903,21 @@ CONFIG_SOUND=m
 # Open Sound System
 #
 CONFIG_SOUND_PRIME=m
-# CONFIG_OBSOLETE_OSS_DRIVER is not set
-# CONFIG_SOUND_FUSION is not set
+# CONFIG_OSS_OBSOLETE_DRIVER is not set
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_ES1371 is not set
 # CONFIG_SOUND_ICH is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
 
 #
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_USB is not set
 
 #
@@ -862,13 +934,44 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 #
 # CONFIG_MMC is not set
 
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
 #
 # InfiniBand support
 #
 # CONFIG_INFINIBAND is not set
 
 #
-# SN Devices
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
 #
 
 #
@@ -888,9 +991,11 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 CONFIG_MINIX_FS=y
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
@@ -920,12 +1025,13 @@ CONFIG_NTFS_RW=y
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -1032,23 +1138,33 @@ CONFIG_NLS_ISO8859_1=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_PREEMPT=y
 CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_DEBUG_INFO is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_4KSTACKS is not set
 # CONFIG_KGDB is not set
 
 #
@@ -1061,6 +1177,10 @@ CONFIG_FRAME_POINTER=y
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=m
 CONFIG_CRYPTO_HMAC=y
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
@@ -1070,6 +1190,8 @@ CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
index e43cf57326bdaca812fd9a12f15ae44d6a9acee9..099e98f14729429566128e0be141b5f6bcb872f6 100644 (file)
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar  2 15:09:42 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 11:38:36 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
 #
 CONFIG_MODULES=y
 # CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 # CONFIG_KMOD is not set
 
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
 #
 # System type
 #
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 CONFIG_SH_RTS7751R2D=y
+# CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
+
+#
+# Processor selection
+#
 CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
 CONFIG_CPU_SUBTYPE_SH7751=y
+CONFIG_CPU_SUBTYPE_SH7751R=y
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_ST40STB1 is not set
 # CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
 CONFIG_MMU=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="mem=64M console=ttySC0,115200 root=/dev/hda1"
+CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x04000000
-CONFIG_MEMORY_SET=y
-# CONFIG_MEMORY_OVERRIDE is not set
-CONFIG_SH_RTC=y
-CONFIG_SH_FPU=y
-CONFIG_ZERO_PAGE_OFFSET=0x00010000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_PREEMPT is not set
-# CONFIG_UBC_WAKEUP is not set
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_SH_WRITETHROUGH is not set
 # CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
 # CONFIG_SH_STORE_QUEUES is not set
-# CONFIG_SMP is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
+
+#
+# RTS7751R2D options
+#
 CONFIG_RTS7751R2D_REV11=y
-CONFIG_SH_PCLK_CALC=y
 CONFIG_SH_PCLK_FREQ=60000000
 
 #
@@ -140,27 +230,43 @@ CONFIG_NR_ONCHIP_DMA_CHANNELS=8
 CONFIG_VOYAGERGX=y
 # CONFIG_HD6446X_SERIES is not set
 CONFIG_HEARTBEAT=y
-CONFIG_RTC_9701JE=y
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00010000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="mem=64M console=ttySC0,115200 root=/dev/hda1"
+
+#
+# Bus options
 #
 CONFIG_PCI=y
 CONFIG_SH_PCIDMA_NONCOHERENT=y
 CONFIG_PCI_AUTO=y
 CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-# CONFIG_PCI_LEGACY_PROC is not set
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
 # CONFIG_PCCARD is not set
 
-#
-# PC-card bridges
-#
-
 #
 # PCI Hotplug Support
 #
@@ -176,6 +282,95 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_FLAT is not set
 # CONFIG_BINFMT_MISC is not set
 
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+CONFIG_WIRELESS_EXT=y
+
 #
 # Device Drivers
 #
@@ -186,6 +381,12 @@ CONFIG_BINFMT_ELF=y
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -204,7 +405,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
@@ -216,18 +416,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_BLK_DEV_INITRD is not set
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -253,7 +444,6 @@ CONFIG_BLK_DEV_IDEDISK=y
 #
 CONFIG_IDE_GENERIC=y
 # CONFIG_BLK_DEV_IDEPCI is not set
-CONFIG_IDE_SH=y
 # CONFIG_IDE_ARM is not set
 # CONFIG_BLK_DEV_IDEDMA is not set
 # CONFIG_IDEDMA_AUTO is not set
@@ -262,7 +452,14 @@ CONFIG_IDE_SH=y
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -272,6 +469,7 @@ CONFIG_IDE_SH=y
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -284,67 +482,8 @@ CONFIG_IDE_SH=y
 # CONFIG_I2O is not set
 
 #
-# Networking support
+# Network device support
 #
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
@@ -356,6 +495,11 @@ CONFIG_NETDEVICES=y
 #
 # CONFIG_ARCNET is not set
 
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
 #
 # Ethernet (10 or 100Mbit)
 #
@@ -364,6 +508,7 @@ CONFIG_MII=y
 # CONFIG_STNIC is not set
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
 
@@ -406,15 +551,22 @@ CONFIG_8139TOO=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
 #
+# CONFIG_CHELSIO_T1 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
 
 #
 # Token Ring devices
@@ -425,6 +577,7 @@ CONFIG_8139TOO=y
 # Wireless LAN (non-hamradio)
 #
 CONFIG_NET_RADIO=y
+# CONFIG_NET_WIRELESS_RTNETLINK is not set
 
 #
 # Obsolete Wireless cards support (pre-802.11)
@@ -434,9 +587,12 @@ CONFIG_NET_RADIO=y
 #
 # Wireless 802.11b ISA/PCI cards support
 #
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
 CONFIG_HERMES=m
 # CONFIG_PLX_HERMES is not set
 # CONFIG_TMD_HERMES is not set
+# CONFIG_NORTEL_HERMES is not set
 # CONFIG_PCI_HERMES is not set
 # CONFIG_ATMEL is not set
 
@@ -444,6 +600,7 @@ CONFIG_HERMES=m
 # Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
 #
 # CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 CONFIG_NET_WIRELESS=y
 
 #
@@ -456,6 +613,8 @@ CONFIG_NET_WIRELESS=y
 # CONFIG_SLIP is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -473,20 +632,10 @@ CONFIG_NET_WIRELESS=y
 # CONFIG_INPUT is not set
 
 #
-# Userland interfaces
-#
-
+# Hardware I/O ports
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 # CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
-# Input Device Drivers
-#
+# CONFIG_GAMEPORT is not set
 
 #
 # Character devices
@@ -503,6 +652,7 @@ CONFIG_SOUND_GAMEPORT=y
 # Non-8250 serial port support
 #
 # CONFIG_SERIAL_SH_SCI is not set
+# CONFIG_SERIAL_JSM is not set
 # CONFIG_UNIX98_PTYS is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -516,7 +666,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -528,15 +678,36 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
 #
 # I2C support
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -546,6 +717,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -555,7 +727,9 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -573,6 +747,9 @@ CONFIG_SND_RAWMIDI=m
 # CONFIG_SND_SEQUENCER is not set
 # CONFIG_SND_MIXER_OSS is not set
 # CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
 
@@ -581,6 +758,8 @@ CONFIG_SND_RAWMIDI=m
 #
 CONFIG_SND_MPU401_UART=m
 CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
 # CONFIG_SND_DUMMY is not set
 # CONFIG_SND_MTPAV is not set
 # CONFIG_SND_SERIAL_U16550 is not set
@@ -589,7 +768,8 @@ CONFIG_SND_OPL3_LIB=m
 #
 # PCI devices
 #
-CONFIG_SND_AC97_CODEC=m
+# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 is not set
 # CONFIG_SND_ALI5451 is not set
 # CONFIG_SND_ATIIXP is not set
 # CONFIG_SND_ATIIXP_MODEM is not set
@@ -598,73 +778,63 @@ CONFIG_SND_AC97_CODEC=m
 # CONFIG_SND_AU8830 is not set
 # CONFIG_SND_AZT3328 is not set
 # CONFIG_SND_BT87X is not set
-# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CA0106 is not set
+# CONFIG_SND_CMIPCI is not set
 # CONFIG_SND_CS4281 is not set
+# CONFIG_SND_CS46XX is not set
 # CONFIG_SND_EMU10K1 is not set
 # CONFIG_SND_EMU10K1X is not set
-# CONFIG_SND_CA0106 is not set
-# CONFIG_SND_KORG1212 is not set
-# CONFIG_SND_MIXART is not set
-# CONFIG_SND_NM256 is not set
-# CONFIG_SND_RME32 is not set
-# CONFIG_SND_RME96 is not set
-# CONFIG_SND_RME9652 is not set
-# CONFIG_SND_HDSP is not set
-# CONFIG_SND_TRIDENT is not set
-CONFIG_SND_YMFPCI=m
-# CONFIG_SND_ALS4000 is not set
-# CONFIG_SND_CMIPCI is not set
 # CONFIG_SND_ENS1370 is not set
 # CONFIG_SND_ENS1371 is not set
 # CONFIG_SND_ES1938 is not set
 # CONFIG_SND_ES1968 is not set
-# CONFIG_SND_MAESTRO3 is not set
 # CONFIG_SND_FM801 is not set
+# CONFIG_SND_HDA_INTEL is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
 # CONFIG_SND_ICE1712 is not set
 # CONFIG_SND_ICE1724 is not set
 # CONFIG_SND_INTEL8X0 is not set
 # CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
 # CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_TRIDENT is not set
 # CONFIG_SND_VIA82XX is not set
 # CONFIG_SND_VIA82XX_MODEM is not set
 # CONFIG_SND_VX222 is not set
+CONFIG_SND_YMFPCI=m
+# CONFIG_SND_AC97_POWER_SAVE is not set
 
 #
 # Open Sound System
 #
 CONFIG_SOUND_PRIME=m
+# CONFIG_OSS_OBSOLETE_DRIVER is not set
 # CONFIG_SOUND_BT878 is not set
-CONFIG_SOUND_CMPCI=m
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
 # CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
 # CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_SONICVIBES is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
 # CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_SOUND_OSS is not set
-# CONFIG_SOUND_ALI5455 is not set
-# CONFIG_SOUND_FORTE is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_AD1980 is not set
-CONFIG_SOUND_VOYAGERGX=m
 
 #
 # USB support
 #
-# CONFIG_USB is not set
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
 #
@@ -677,31 +847,67 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 #
 # CONFIG_MMC is not set
 
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
 #
 # InfiniBand support
 #
 # CONFIG_INFINIBAND is not set
 
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 CONFIG_MINIX_FS=y
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -724,12 +930,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -758,6 +965,7 @@ CONFIG_RAMFS=y
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
 
 #
 # Partition Types
@@ -818,8 +1026,14 @@ CONFIG_OPROFILE=y
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_KGDB is not set
@@ -835,13 +1049,11 @@ CONFIG_OPROFILE=y
 #
 # CONFIG_CRYPTO is not set
 
-#
-# Hardware crypto devices
-#
-
 #
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
index 4b71cd692fa5fffb70c25c720d765d06b9f1db2c..8a217908b81f2b4172049c575327af74fd845c34 100644 (file)
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar  2 15:09:43 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 11:43:22 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_SWAP is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_KALLSYMS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
 #
 # CONFIG_MODULES is not set
 
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+
 #
 # System type
 #
+CONFIG_SOLUTION_ENGINE=y
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 CONFIG_SH_7300_SOLUTION_ENGINE=y
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
+
+#
+# Processor selection
+#
 CONFIG_CPU_SH3=y
-# CONFIG_CPU_SH4 is not set
+
+#
+# SH-2 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
 CONFIG_CPU_SUBTYPE_SH7300=y
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
 # CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_ST40STB1 is not set
 # CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
 CONFIG_MMU=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttySC0,38400 root=/dev/ram0"
+CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x04000000
-# CONFIG_MEMORY_OVERRIDE is not set
-CONFIG_SH_DSP=y
-# CONFIG_SH_ADC is not set
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00210000
-CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_PREEMPT is not set
-# CONFIG_UBC_WAKEUP is not set
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_SH_WRITETHROUGH is not set
 # CONFIG_SH_OCRAM is not set
-# CONFIG_SMP is not set
-# CONFIG_SH_PCLK_CALC is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_SH_FPU_EMU is not set
+CONFIG_SH_DSP=y
+# CONFIG_SH_ADC is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
 CONFIG_SH_PCLK_FREQ=33333333
 
 #
@@ -128,17 +215,34 @@ CONFIG_SH_PCLK_FREQ=33333333
 CONFIG_HEARTBEAT=y
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
 #
-# CONFIG_PCI is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
 
 #
-# PCCARD (PCMCIA/CardBus) support
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00210000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC0,38400 root=/dev/ram0"
+
+#
+# Bus options
 #
-# CONFIG_PCCARD is not set
+# CONFIG_PCI is not set
 
 #
-# PC-card bridges
+# PCCARD (PCMCIA/CardBus) support
 #
 
 #
@@ -153,10 +257,14 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 
 #
-# SH initrd options
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
 #
-CONFIG_EMBEDDED_RAMDISK=y
-CONFIG_EMBEDDED_RAMDISK_IMAGE="ramdisk.gz"
+# CONFIG_NET is not set
 
 #
 # Device Drivers
@@ -167,7 +275,11 @@ CONFIG_EMBEDDED_RAMDISK_IMAGE="ramdisk.gz"
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
 
 #
 # Memory Technology Devices (MTD)
@@ -186,25 +298,15 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
 
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-
 #
 # ATA/ATAPI/MFM/RLL support
 #
@@ -213,7 +315,14 @@ CONFIG_IOSCHED_NOOP=y
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -223,6 +332,7 @@ CONFIG_IOSCHED_NOOP=y
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -232,13 +342,6 @@ CONFIG_IOSCHED_NOOP=y
 # I2O device support
 #
 
-#
-# Networking support
-#
-# CONFIG_NET is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
 #
 # ISDN subsystem
 #
@@ -252,6 +355,7 @@ CONFIG_IOSCHED_NOOP=y
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -265,18 +369,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
 #
 # Input Device Drivers
 #
@@ -286,6 +378,16 @@ CONFIG_SERIO=y
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
 #
 # Character devices
 #
@@ -301,6 +403,7 @@ CONFIG_SERIO=y
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -328,7 +431,7 @@ CONFIG_WATCHDOG=y
 #
 CONFIG_SOFT_WATCHDOG=y
 # CONFIG_SH_WDT is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -336,18 +439,38 @@ CONFIG_SOFT_WATCHDOG=y
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
 #
 # I2C support
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -357,6 +480,7 @@ CONFIG_SOFT_WATCHDOG=y
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -365,7 +489,9 @@ CONFIG_SOFT_WATCHDOG=y
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -377,9 +503,10 @@ CONFIG_SOFT_WATCHDOG=y
 #
 # CONFIG_USB_ARCH_HAS_HCD is not set
 # CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
 #
@@ -392,31 +519,65 @@ CONFIG_SOFT_WATCHDOG=y
 #
 # CONFIG_MMC is not set
 
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
 #
 # InfiniBand support
 #
-# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
 
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -436,14 +597,13 @@ CONFIG_DNOTIFY=y
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -481,8 +641,16 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
 CONFIG_SH_STANDARD_BIOS=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_KGDB=y
@@ -519,13 +687,10 @@ CONFIG_KGDB_DEFBITS_8=y
 #
 # CONFIG_CRYPTO is not set
 
-#
-# Hardware crypto devices
-#
-
 #
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
index fe19feb95ca9a4a918761a23459d284db9c809c6..1a766153cbb01d6c6fedd52122b2b2241f8489d0 100644 (file)
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar  2 15:09:44 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 11:44:45 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_KALLSYMS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
 #
 CONFIG_MODULES=y
 # CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 # CONFIG_KMOD is not set
 
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+
 #
 # System type
 #
+CONFIG_SOLUTION_ENGINE=y
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 CONFIG_SH_73180_SOLUTION_ENGINE=y
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
 # CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
+
+#
+# Processor selection
+#
 CONFIG_CPU_SH4=y
+CONFIG_CPU_SH4A=y
+CONFIG_CPU_SH4AL_DSP=y
+
+#
+# SH-2 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
 # CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
-CONFIG_CPU_SUBTYPE_SH73180=y
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_ST40STB1 is not set
 # CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+CONFIG_CPU_SUBTYPE_SH73180=y
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
 CONFIG_MMU=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttySC0,38400 root=/dev/ram"
+CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x02000000
-# CONFIG_MEMORY_OVERRIDE is not set
-# CONFIG_SH_FPU is not set
-CONFIG_ZERO_PAGE_OFFSET=0x00010000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_PREEMPT is not set
-# CONFIG_UBC_WAKEUP is not set
+CONFIG_32BIT=y
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_SH_WRITETHROUGH is not set
 # CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_SH_FPU is not set
+# CONFIG_SH_FPU_EMU is not set
+CONFIG_SH_DSP=y
 # CONFIG_SH_STORE_QUEUES is not set
-# CONFIG_SMP is not set
-# CONFIG_SH_PCLK_CALC is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
 CONFIG_SH_PCLK_FREQ=27000000
 
 #
@@ -134,17 +222,34 @@ CONFIG_SH_PCLK_FREQ=27000000
 CONFIG_HEARTBEAT=y
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
 #
-# CONFIG_PCI is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
 
 #
-# PCCARD (PCMCIA/CardBus) support
+# Boot options
 #
-# CONFIG_PCCARD is not set
+CONFIG_ZERO_PAGE_OFFSET=0x00010000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC0,38400 root=/dev/ram"
 
 #
-# PC-card bridges
+# Bus options
+#
+# CONFIG_PCI is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
 #
 
 #
@@ -159,10 +264,14 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 
 #
-# SH initrd options
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
 #
-CONFIG_EMBEDDED_RAMDISK=y
-CONFIG_EMBEDDED_RAMDISK_IMAGE="ramdisk.gz"
+# CONFIG_NET is not set
 
 #
 # Device Drivers
@@ -173,7 +282,11 @@ CONFIG_EMBEDDED_RAMDISK_IMAGE="ramdisk.gz"
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
 
 #
 # Memory Technology Devices (MTD)
@@ -192,26 +305,16 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
 
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-
 #
 # ATA/ATAPI/MFM/RLL support
 #
@@ -220,7 +323,14 @@ CONFIG_IOSCHED_NOOP=y
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -230,6 +340,7 @@ CONFIG_IOSCHED_NOOP=y
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -239,13 +350,6 @@ CONFIG_IOSCHED_NOOP=y
 # I2O device support
 #
 
-#
-# Networking support
-#
-# CONFIG_NET is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
 #
 # ISDN subsystem
 #
@@ -261,20 +365,10 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_INPUT is not set
 
 #
-# Userland interfaces
-#
-
+# Hardware I/O ports
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 # CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
-# Input Device Drivers
-#
+# CONFIG_GAMEPORT is not set
 
 #
 # Character devices
@@ -291,6 +385,7 @@ CONFIG_SOUND_GAMEPORT=y
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -313,7 +408,7 @@ CONFIG_WATCHDOG=y
 #
 # CONFIG_SOFT_WATCHDOG is not set
 # CONFIG_SH_WDT is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -321,18 +416,38 @@ CONFIG_WATCHDOG=y
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
 #
 # I2C support
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -342,6 +457,7 @@ CONFIG_WATCHDOG=y
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -350,6 +466,7 @@ CONFIG_WATCHDOG=y
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
 
 #
@@ -362,9 +479,10 @@ CONFIG_WATCHDOG=y
 #
 # CONFIG_USB_ARCH_HAS_HCD is not set
 # CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
 #
@@ -377,31 +495,65 @@ CONFIG_WATCHDOG=y
 #
 # CONFIG_MMC is not set
 
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
 #
 # InfiniBand support
 #
-# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
 
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -421,12 +573,10 @@ CONFIG_DNOTIFY=y
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 # CONFIG_SYSFS is not set
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
 CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
@@ -467,8 +617,13 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
 CONFIG_SH_STANDARD_BIOS=y
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_EARLY_PRINTK is not set
@@ -478,20 +633,16 @@ CONFIG_SH_STANDARD_BIOS=y
 # Security options
 #
 # CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
 
 #
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
 
-#
-# Hardware crypto devices
-#
-
 #
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
index 948e507b52beeb596b0d7c0b743d8db34d09769e..84c0075e2ad47c6492f0d5d7ba081097565e8fbd 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.17
-# Mon Aug  7 20:14:44 2006
+# Linux kernel version: 2.6.18
+# Tue Oct  3 11:46:17 2006
 #
 CONFIG_SUPERH=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
@@ -10,6 +10,7 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
@@ -25,16 +26,20 @@ CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -46,10 +51,10 @@ CONFIG_BASE_FULL=y
 # CONFIG_EPOLL is not set
 # CONFIG_SHMEM is not set
 CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
-CONFIG_OBSOLETE_INTERMODULE=y
 
 #
 # Loadable module support
@@ -64,6 +69,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -115,6 +121,7 @@ CONFIG_SH_7343_SOLUTION_ENGINE=y
 #
 CONFIG_CPU_SH4=y
 CONFIG_CPU_SH4A=y
+CONFIG_CPU_SH4AL_DSP=y
 
 #
 # SH-2 Processor Support
@@ -153,11 +160,15 @@ CONFIG_CPU_SH4A=y
 #
 # SH-4A Processor Support
 #
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
-CONFIG_CPU_SUBTYPE_SH7343=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+CONFIG_CPU_SUBTYPE_SH7343=y
+
 #
 # Memory management options
 #
@@ -166,6 +177,7 @@ CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x01000000
 CONFIG_32BIT=y
+CONFIG_VSYSCALL=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -174,6 +186,7 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
 
 #
 # Cache configuration
@@ -274,6 +287,9 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -292,12 +308,16 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
 # CONFIG_INET_DIAG is not set
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 
 #
@@ -323,7 +343,6 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -351,6 +370,7 @@ CONFIG_TCP_CONG_BIC=y
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
 
 #
 # Connector - unified userspace <-> kernelspace linker
@@ -376,6 +396,7 @@ CONFIG_MTD_BLOCK=y
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -408,7 +429,6 @@ CONFIG_MTD_RAM=y
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 # CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_SOLUTIONENGINE is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -466,6 +486,12 @@ CONFIG_MTD_RAM=y
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -506,7 +532,6 @@ CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_STNIC is not set
 CONFIG_SMC91X=y
-# CONFIG_NE2000 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -550,6 +575,7 @@ CONFIG_SMC91X=y
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -581,6 +607,7 @@ CONFIG_INPUT=y
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -609,7 +636,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -641,10 +668,10 @@ CONFIG_I2C_CHARDEV=y
 #
 # I2C Hardware Bus support
 #
+# CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_STUB is not set
 # CONFIG_I2C_PCA_ISA is not set
-CONFIG_I2C_SH7343=y
 
 #
 # Miscellaneous I2C Chip support
@@ -670,7 +697,6 @@ CONFIG_I2C_SH7343=y
 #
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -698,30 +724,16 @@ CONFIG_VIDEO_V4L2=y
 # Video Capture Adapters
 #
 # CONFIG_VIDEO_ADV_DEBUG is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
 # CONFIG_VIDEO_VIVI is not set
 # CONFIG_VIDEO_CPIA is not set
 # CONFIG_VIDEO_SAA5246A is not set
 # CONFIG_VIDEO_SAA5249 is not set
 # CONFIG_TUNER_3036 is not set
-# CONFIG_VIDEO_OVCAMCHIP is not set
-
-#
-# Encoders and Decoders
-#
-# CONFIG_VIDEO_MSP3400 is not set
-# CONFIG_VIDEO_CS53L32A is not set
-# CONFIG_VIDEO_WM8775 is not set
-# CONFIG_VIDEO_WM8739 is not set
-# CONFIG_VIDEO_CX25840 is not set
-# CONFIG_VIDEO_SAA711X is not set
-# CONFIG_VIDEO_SAA7127 is not set
-# CONFIG_VIDEO_UPD64031A is not set
-# CONFIG_VIDEO_UPD64083 is not set
 
 #
 # Radio Adapters
 #
-# CONFIG_RADIO_MAESTRO is not set
 
 #
 # Digital Video Broadcasting Devices
@@ -731,12 +743,13 @@ CONFIG_VIDEO_V4L2=y
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 CONFIG_FB=y
 # CONFIG_FB_CFB_FILLRECT is not set
 # CONFIG_FB_CFB_COPYAREA is not set
 # CONFIG_FB_CFB_IMAGEBLIT is not set
 # CONFIG_FB_MACMODES is not set
-CONFIG_FB_FIRMWARE_EDID=y
+# CONFIG_FB_BACKLIGHT is not set
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
 # CONFIG_FB_EPSON1355 is not set
@@ -788,12 +801,6 @@ CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_SERIAL_U16550 is not set
 # CONFIG_SND_MPU401 is not set
 
-#
-# SuperH devices
-#
-CONFIG_SH7343_SIU=m
-CONFIG_AK4537_CODEC=y
-
 #
 # Open Sound System
 #
@@ -846,6 +853,19 @@ CONFIG_AK4537_CODEC=y
 #
 # CONFIG_RTC_CLASS is not set
 
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
 #
 # File systems
 #
@@ -883,8 +903,10 @@ CONFIG_AK4537_CODEC=y
 #
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
@@ -905,6 +927,7 @@ CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
 # CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
@@ -962,7 +985,9 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DEBUG_BUGVERBOSE is not set
@@ -982,10 +1007,6 @@ CONFIG_LOG_BUF_SHIFT=14
 #
 # CONFIG_CRYPTO is not set
 
-#
-# Hardware crypto devices
-#
-
 #
 # Library routines
 #
index e4a14602b169a7fb4e4a7de32abacf760ff68547..06ebd6ec0cdb87bf560368451568e939ae57ae8f 100644 (file)
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar  2 15:09:45 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 12:03:04 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_SWAP is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_KALLSYMS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
 #
 CONFIG_MODULES=y
 # CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
 #
 # System type
 #
+CONFIG_SOLUTION_ENGINE=y
 CONFIG_SH_SOLUTION_ENGINE=y
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
+
+#
+# Processor selection
+#
 CONFIG_CPU_SH3=y
-# CONFIG_CPU_SH4 is not set
+
+#
+# SH-2 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 CONFIG_CPU_SUBTYPE_SH7705=y
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
 # CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_ST40STB1 is not set
 # CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
-CONFIG_SH7705_CACHE_32KB=y
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
 CONFIG_MMU=y
-# CONFIG_CMDLINE_BOOL is not set
+CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x02000000
-CONFIG_MEMORY_SET=y
-# CONFIG_MEMORY_OVERRIDE is not set
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+CONFIG_SH7705_CACHE_32KB=y
+# CONFIG_SH_DIRECT_MAPPED is not set
+# CONFIG_SH_WRITETHROUGH is not set
+# CONFIG_SH_OCRAM is not set
 # CONFIG_CF_ENABLER is not set
-CONFIG_SH_RTC=y
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_SH_FPU_EMU is not set
 # CONFIG_SH_DSP is not set
 # CONFIG_SH_ADC is not set
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_PREEMPT=y
-# CONFIG_UBC_WAKEUP is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_PINT_IRQ=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
 CONFIG_SH_PCLK_FREQ=33333333
 
 #
@@ -139,17 +226,34 @@ CONFIG_SH_PCLK_FREQ=33333333
 CONFIG_HEARTBEAT=y
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
 #
-# CONFIG_PCI is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
 
 #
-# PCCARD (PCMCIA/CardBus) support
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Bus options
 #
-# CONFIG_PCCARD is not set
+# CONFIG_PCI is not set
 
 #
-# PC-card bridges
+# PCCARD (PCMCIA/CardBus) support
 #
 
 #
@@ -164,9 +268,95 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 
 #
-# SH initrd options
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
 #
-# CONFIG_EMBEDDED_RAMDISK is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
 
 #
 # Device Drivers
@@ -177,15 +367,20 @@ CONFIG_BINFMT_ELF=y
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
 
 #
 # Memory Technology Devices (MTD)
 #
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
 
@@ -197,6 +392,8 @@ CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -217,22 +414,19 @@ CONFIG_MTD_CFI_I2=y
 # CONFIG_MTD_CFI_I8 is not set
 # CONFIG_MTD_CFI_INTELEXT is not set
 CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_CFI_AMDSTD_RETRY=0
 # CONFIG_MTD_CFI_STAA is not set
 CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 # CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_SOLUTIONENGINE=y
-CONFIG_MTD_SUPERH_RESERVE=0x300000
-# CONFIG_MTD_MPC1211 is not set
-# CONFIG_MTD_RTS7751R2D is not set
+# CONFIG_MTD_PLATRAM is not set
 
 #
 # Self-contained MTD device drivers
@@ -240,7 +434,6 @@ CONFIG_MTD_SUPERH_RESERVE=0x300000
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
 # CONFIG_MTD_BLOCK2MTD is not set
 
 #
@@ -255,6 +448,11 @@ CONFIG_MTD_SUPERH_RESERVE=0x300000
 #
 # CONFIG_MTD_NAND is not set
 
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
 #
 # Parallel port support
 #
@@ -267,25 +465,15 @@ CONFIG_MTD_SUPERH_RESERVE=0x300000
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -296,7 +484,14 @@ CONFIG_IOSCHED_AS=y
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -306,6 +501,7 @@ CONFIG_IOSCHED_AS=y
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -316,76 +512,19 @@ CONFIG_IOSCHED_AS=y
 #
 
 #
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
+# Network device support
 #
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
 #
 # Ethernet (10 or 100Mbit)
 #
@@ -422,10 +561,14 @@ CONFIG_PPP_ASYNC=y
 # CONFIG_PPP_SYNC_TTY is not set
 CONFIG_PPP_DEFLATE=y
 # CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPP_MPPE is not set
 # CONFIG_PPPOE is not set
 # CONFIG_SLIP is not set
+CONFIG_SLHC=y
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -441,6 +584,7 @@ CONFIG_PPP_DEFLATE=y
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -451,18 +595,6 @@ CONFIG_INPUT=y
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
 #
 # Input Device Drivers
 #
@@ -472,6 +604,16 @@ CONFIG_SERIO=y
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
 #
 # Character devices
 #
@@ -487,6 +629,7 @@ CONFIG_SERIO=y
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -502,7 +645,7 @@ CONFIG_UNIX98_PTYS=y
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -510,18 +653,38 @@ CONFIG_UNIX98_PTYS=y
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
 #
 # I2C support
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -531,6 +694,7 @@ CONFIG_UNIX98_PTYS=y
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -540,6 +704,7 @@ CONFIG_UNIX98_PTYS=y
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
 
 #
@@ -552,9 +717,10 @@ CONFIG_UNIX98_PTYS=y
 #
 # CONFIG_USB_ARCH_HAS_HCD is not set
 # CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
 #
@@ -567,31 +733,65 @@ CONFIG_UNIX98_PTYS=y
 #
 # CONFIG_MMC is not set
 
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
 #
 # InfiniBand support
 #
-# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
 
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -611,9 +811,8 @@ CONFIG_DNOTIFY=y
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 # CONFIG_SYSFS is not set
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
@@ -632,8 +831,9 @@ CONFIG_RAMFS=y
 # CONFIG_JFFS_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_JFFS2_FS_NOR_ECC is not set
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
@@ -655,6 +855,7 @@ CONFIG_NFS_FS=y
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -663,6 +864,7 @@ CONFIG_SUNRPC=y
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
 
 #
 # Partition Types
@@ -683,9 +885,13 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_PREEMPT=y
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_KGDB is not set
 
@@ -693,22 +899,19 @@ CONFIG_DEBUG_PREEMPT=y
 # Security options
 #
 # CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
 
 #
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
 
-#
-# Hardware crypto devices
-#
-
 #
 # Library routines
 #
 CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
index 6dc31584752a7a20f9de830ae629ddcd8c572bc4..5d357d68b234e866d26a2efb4e27297e11d4b350 100644 (file)
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar  2 15:09:46 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 11:49:01 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
 #
 CONFIG_MODULES=y
 # CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
 #
 # System type
 #
+CONFIG_SOLUTION_ENGINE=y
 CONFIG_SH_SOLUTION_ENGINE=y
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
+
+#
+# Processor selection
+#
 CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
 CONFIG_CPU_SUBTYPE_SH7750=y
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
 # CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_ST40STB1 is not set
 # CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
 CONFIG_MMU=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttySC1,38400 root=/dev/nfs ip=bootp"
+CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x02000000
-CONFIG_MEMORY_SET=y
-# CONFIG_MEMORY_OVERRIDE is not set
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
+# CONFIG_SH_WRITETHROUGH is not set
+# CONFIG_SH_OCRAM is not set
 CONFIG_CF_ENABLER=y
 # CONFIG_CF_AREA5 is not set
 CONFIG_CF_AREA6=y
 CONFIG_CF_BASE_ADDR=0xb8000000
-CONFIG_SH_RTC=y
-CONFIG_SH_FPU=y
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
+
+#
+# Processor features
+#
 CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_PREEMPT is not set
-# CONFIG_UBC_WAKEUP is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
 # CONFIG_SH_STORE_QUEUES is not set
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
-CONFIG_SH_PCLK_FREQ=49876504
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_PCLK_FREQ=50000000
 
 #
 # CPU Frequency scaling
@@ -144,17 +231,34 @@ CONFIG_SH_PCLK_FREQ=49876504
 CONFIG_HEARTBEAT=y
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
 #
-# CONFIG_PCI is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
 
 #
-# PCCARD (PCMCIA/CardBus) support
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC1,38400 root=/dev/nfs ip=bootp"
+
+#
+# Bus options
 #
-# CONFIG_PCCARD is not set
+# CONFIG_PCI is not set
 
 #
-# PC-card bridges
+# PCCARD (PCMCIA/CardBus) support
 #
 
 #
@@ -168,6 +272,98 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_FLAT is not set
 # CONFIG_BINFMT_MISC is not set
 
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
 #
 # Device Drivers
 #
@@ -177,15 +373,20 @@ CONFIG_BINFMT_ELF=y
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
 
 #
 # Memory Technology Devices (MTD)
 #
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
 
@@ -197,6 +398,8 @@ CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -217,22 +420,19 @@ CONFIG_MTD_CFI_I2=y
 # CONFIG_MTD_CFI_I8 is not set
 # CONFIG_MTD_CFI_INTELEXT is not set
 CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_CFI_AMDSTD_RETRY=0
 # CONFIG_MTD_CFI_STAA is not set
 CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 CONFIG_MTD_ROM=y
 # CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 # CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_SOLUTIONENGINE=y
-CONFIG_MTD_SUPERH_RESERVE=0x00010000
-# CONFIG_MTD_MPC1211 is not set
-# CONFIG_MTD_RTS7751R2D is not set
+# CONFIG_MTD_PLATRAM is not set
 
 #
 # Self-contained MTD device drivers
@@ -240,7 +440,6 @@ CONFIG_MTD_SUPERH_RESERVE=0x00010000
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
 # CONFIG_MTD_BLOCK2MTD is not set
 
 #
@@ -255,6 +454,11 @@ CONFIG_MTD_SUPERH_RESERVE=0x00010000
 #
 # CONFIG_MTD_NAND is not set
 
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
 #
 # Parallel port support
 #
@@ -267,23 +471,12 @@ CONFIG_MTD_SUPERH_RESERVE=0x00010000
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -294,7 +487,14 @@ CONFIG_IOSCHED_CFQ=y
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -304,6 +504,7 @@ CONFIG_IOSCHED_CFQ=y
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -314,77 +515,19 @@ CONFIG_IOSCHED_CFQ=y
 #
 
 #
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
+# Network device support
 #
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
 #
 # Ethernet (10 or 100Mbit)
 #
@@ -418,6 +561,8 @@ CONFIG_STNIC=y
 # CONFIG_SLIP is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -435,20 +580,10 @@ CONFIG_STNIC=y
 # CONFIG_INPUT is not set
 
 #
-# Userland interfaces
+# Hardware I/O ports
 #
-
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 # CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
-# Input Device Drivers
-#
+# CONFIG_GAMEPORT is not set
 
 #
 # Character devices
@@ -462,12 +597,14 @@ CONFIG_SOUND_GAMEPORT=y
 CONFIG_SERIAL_8250=y
 # CONFIG_SERIAL_8250_CONSOLE is not set
 CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -491,7 +628,8 @@ CONFIG_WATCHDOG=y
 #
 # CONFIG_SOFT_WATCHDOG is not set
 CONFIG_SH_WDT=y
-# CONFIG_RTC is not set
+# CONFIG_SH_WDT_MMAP is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -499,18 +637,38 @@ CONFIG_SH_WDT=y
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
 #
 # I2C support
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -520,6 +678,7 @@ CONFIG_SH_WDT=y
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -529,7 +688,9 @@ CONFIG_SH_WDT=y
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -541,9 +702,10 @@ CONFIG_SH_WDT=y
 #
 # CONFIG_USB_ARCH_HAS_HCD is not set
 # CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
 #
@@ -556,30 +718,64 @@ CONFIG_SH_WDT=y
 #
 # CONFIG_MMC is not set
 
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
 #
 # InfiniBand support
 #
-# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
 
 #
 # File systems
 #
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -599,14 +795,14 @@ CONFIG_DNOTIFY=y
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -621,8 +817,9 @@ CONFIG_RAMFS=y
 # CONFIG_JFFS_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_JFFS2_FS_NOR_ECC is not set
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
@@ -644,6 +841,7 @@ CONFIG_NFS_FS=y
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -652,6 +850,7 @@ CONFIG_SUNRPC=y
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
 
 #
 # Partition Types
@@ -667,6 +866,7 @@ CONFIG_PARTITION_ADVANCED=y
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 
 #
@@ -682,8 +882,14 @@ CONFIG_PARTITION_ADVANCED=y
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_KGDB is not set
@@ -699,15 +905,13 @@ CONFIG_PARTITION_ADVANCED=y
 #
 # CONFIG_CRYPTO is not set
 
-#
-# Hardware crypto devices
-#
-
 #
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
index 1ce02894745951e16b78f9fd84d423aa6877c4eb..a9095593f8f362d3c2be237c84014f3aafd6f3f9 100644 (file)
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar  2 15:09:48 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 12:10:12 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
 #
 CONFIG_MODULES=y
 # CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 # CONFIG_KMOD is not set
 
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
 #
 # System type
 #
+CONFIG_SOLUTION_ENGINE=y
 # CONFIG_SH_SOLUTION_ENGINE is not set
 CONFIG_SH_7751_SOLUTION_ENGINE=y
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
+
+#
+# Processor selection
+#
 CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
 CONFIG_CPU_SUBTYPE_SH7751=y
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_ST40STB1 is not set
 # CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
 CONFIG_MMU=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttySC1,38400"
+CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x04000000
-CONFIG_MEMORY_SET=y
-# CONFIG_MEMORY_OVERRIDE is not set
-CONFIG_SH_RTC=y
-CONFIG_SH_FPU=y
-CONFIG_ZERO_PAGE_OFFSET=0x00010000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_PREEMPT is not set
-# CONFIG_UBC_WAKEUP is not set
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_SH_WRITETHROUGH is not set
 # CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
 # CONFIG_SH_STORE_QUEUES is not set
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
-CONFIG_SH_PCLK_FREQ=60013568
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_PCLK_FREQ=60000000
 
 #
 # CPU Frequency scaling
@@ -139,28 +226,39 @@ CONFIG_SH_PCLK_FREQ=60013568
 CONFIG_HEARTBEAT=y
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
 #
-CONFIG_PCI=y
-# CONFIG_SH_PCIDMA_NONCOHERENT is not set
-CONFIG_PCI_AUTO=y
-CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-# CONFIG_PCI_LEGACY_PROC is not set
-# CONFIG_PCI_NAMES is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
 
 #
-# PCCARD (PCMCIA/CardBus) support
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00010000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC1,38400"
+
 #
-# CONFIG_PCCARD is not set
+# Bus options
+#
+# CONFIG_PCI is not set
 
 #
-# PC-card bridges
+# PCCARD (PCMCIA/CardBus) support
 #
 
 #
 # PCI Hotplug Support
 #
-# CONFIG_HOTPLUG_PCI is not set
 
 #
 # Executable file formats
@@ -170,9 +268,115 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 
 #
-# SH initrd options
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_DEBUG=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_QUEUE=y
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
 #
-# CONFIG_EMBEDDED_RAMDISK is not set
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
 
 #
 # Device Drivers
@@ -183,15 +387,20 @@ CONFIG_BINFMT_ELF=y
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
 
 #
 # Memory Technology Devices (MTD)
 #
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
 
@@ -203,6 +412,8 @@ CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -223,30 +434,26 @@ CONFIG_MTD_CFI_I2=y
 # CONFIG_MTD_CFI_I8 is not set
 # CONFIG_MTD_CFI_INTELEXT is not set
 CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_CFI_AMDSTD_RETRY=0
 # CONFIG_MTD_CFI_STAA is not set
 CONFIG_MTD_CFI_UTIL=y
 CONFIG_MTD_RAM=y
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 # CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_SOLUTIONENGINE is not set
-# CONFIG_MTD_MPC1211 is not set
-# CONFIG_MTD_RTS7751R2D is not set
+# CONFIG_MTD_PLATRAM is not set
 
 #
 # Self-contained MTD device drivers
 #
-# CONFIG_MTD_PMC551 is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
 # CONFIG_MTD_BLOCK2MTD is not set
 
 #
@@ -261,6 +468,11 @@ CONFIG_MTD_RAM=y
 #
 # CONFIG_MTD_NAND is not set
 
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
 #
 # Parallel port support
 #
@@ -273,30 +485,15 @@ CONFIG_MTD_RAM=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -307,7 +504,14 @@ CONFIG_IOSCHED_CFQ=y
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -317,109 +521,29 @@ CONFIG_IOSCHED_CFQ=y
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
 #
-# CONFIG_IEEE1394 is not set
 
 #
 # I2O device support
 #
-# CONFIG_I2O is not set
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-CONFIG_NETFILTER_DEBUG=y
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_CONNTRACK is not set
-# CONFIG_IP_NF_CONNTRACK_MARK is not set
-CONFIG_IP_NF_QUEUE=y
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
-# Network testing
+# Network device support
 #
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
 
 #
-# ARCnet devices
+# PHY device support
 #
-# CONFIG_ARCNET is not set
+# CONFIG_PHYLIB is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -427,60 +551,19 @@ CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_STNIC is not set
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
 
-#
-# Tulip family network device support
-#
-# CONFIG_NET_TULIP is not set
-# CONFIG_HP100 is not set
-CONFIG_NET_PCI=y
-CONFIG_PCNET32=y
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_B44 is not set
-# CONFIG_FORCEDETH is not set
-# CONFIG_DGRS is not set
-# CONFIG_EEPRO100 is not set
-# CONFIG_E100 is not set
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_8139CP is not set
-# CONFIG_8139TOO is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_TLAN is not set
-# CONFIG_VIA_RHINE is not set
-
 #
 # Ethernet (1000 Mbit)
 #
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_VIA_VELOCITY is not set
-# CONFIG_TIGON3 is not set
 
 #
 # Ethernet (10000 Mbit)
 #
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
 
 #
 # Token Ring devices
 #
-# CONFIG_TR is not set
 
 #
 # Wireless LAN (non-hamradio)
@@ -491,12 +574,12 @@ CONFIG_PCNET32=y
 # Wan interfaces
 #
 # CONFIG_WAN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -514,20 +597,10 @@ CONFIG_PCNET32=y
 # CONFIG_INPUT is not set
 
 #
-# Userland interfaces
-#
-
+# Hardware I/O ports
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 # CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
-# Input Device Drivers
-#
+# CONFIG_GAMEPORT is not set
 
 #
 # Character devices
@@ -564,33 +637,46 @@ CONFIG_WATCHDOG=y
 #
 # CONFIG_SOFT_WATCHDOG is not set
 # CONFIG_SH_WDT is not set
-
-#
-# PCI-based Watchdog Cards
-#
-# CONFIG_PCIPCWATCHDOG is not set
-# CONFIG_WDTPCI is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
 
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
 #
 # I2C support
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -600,6 +686,7 @@ CONFIG_WATCHDOG=y
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -609,7 +696,9 @@ CONFIG_WATCHDOG=y
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -619,12 +708,12 @@ CONFIG_WATCHDOG=y
 #
 # USB support
 #
-# CONFIG_USB is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
 #
@@ -637,31 +726,66 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 #
 # CONFIG_MMC is not set
 
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
 #
 # InfiniBand support
 #
-# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
 
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -681,14 +805,14 @@ CONFIG_DNOTIFY=y
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -703,8 +827,9 @@ CONFIG_RAMFS=y
 # CONFIG_JFFS_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_JFFS2_FS_NOR_ECC is not set
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
@@ -726,6 +851,7 @@ CONFIG_JFFS2_RTIME=y
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
 
 #
 # Partition Types
@@ -746,8 +872,14 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_KGDB is not set
@@ -763,15 +895,13 @@ CONFIG_MSDOS_PARTITION=y
 #
 # CONFIG_CRYPTO is not set
 
-#
-# Hardware crypto devices
-#
-
 #
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
index 078f78c7fe53bf756ac9d48f554aef0a93c53a7e..9fd5ea7304e5aef2fc99ed4216cd8fd77dcea730 100644 (file)
@@ -1,51 +1,63 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar  2 15:09:49 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 12:13:26 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-# CONFIG_CLEAN_COMPILE is not set
-CONFIG_BROKEN=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 CONFIG_POSIX_MQUEUE=y
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
-# CONFIG_EMBEDDED is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -53,81 +65,154 @@ CONFIG_CC_ALIGN_JUMPS=0
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
 CONFIG_MODVERSIONS=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
 #
 # System type
 #
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 CONFIG_SH_SH03=y
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
+
+#
+# Processor selection
+#
 CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
 CONFIG_CPU_SUBTYPE_SH7751=y
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_ST40STB1 is not set
 # CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
 CONFIG_MMU=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttySC1,115200 mem=64M root=/dev/nfs"
+CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
-CONFIG_MEMORY_SET=y
-# CONFIG_MEMORY_OVERRIDE is not set
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
+# CONFIG_SH_WRITETHROUGH is not set
+# CONFIG_SH_OCRAM is not set
 CONFIG_CF_ENABLER=y
 CONFIG_CF_AREA5=y
 # CONFIG_CF_AREA6 is not set
 CONFIG_CF_BASE_ADDR=0xb4000000
-CONFIG_SH_RTC=y
-CONFIG_SH_FPU=y
-CONFIG_ZERO_PAGE_OFFSET=0x00004000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
+
+#
+# Processor features
+#
 CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_PREEMPT=y
-# CONFIG_UBC_WAKEUP is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
 # CONFIG_SH_STORE_QUEUES is not set
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
-CONFIG_SH_PCLK_FREQ=49876504
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_PCLK_FREQ=60000000
 
 #
 # CPU Frequency scaling
@@ -146,24 +231,42 @@ CONFIG_SH_PCLK_FREQ=49876504
 CONFIG_HEARTBEAT=y
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00004000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC1,115200 mem=64M root=/dev/nfs"
+
+#
+# Bus options
 #
 CONFIG_PCI=y
 CONFIG_SH_PCIDMA_NONCOHERENT=y
 CONFIG_PCI_AUTO=y
 CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
 # CONFIG_PCCARD is not set
 
-#
-# PC-card bridges
-#
-
 #
 # PCI Hotplug Support
 #
@@ -180,9 +283,96 @@ CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=y
 
 #
-# SH initrd options
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
 #
-# CONFIG_EMBEDDED_RAMDISK is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
 
 #
 # Device Drivers
@@ -194,6 +384,12 @@ CONFIG_BINFMT_MISC=y
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -212,7 +408,6 @@ CONFIG_BINFMT_MISC=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
@@ -225,18 +420,9 @@ CONFIG_BLK_DEV_NBD=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -263,7 +449,6 @@ CONFIG_BLK_DEV_IDEFLOPPY=m
 #
 CONFIG_IDE_GENERIC=y
 # CONFIG_BLK_DEV_IDEPCI is not set
-CONFIG_IDE_SH=y
 # CONFIG_IDE_ARM is not set
 # CONFIG_BLK_DEV_IDEDMA is not set
 # CONFIG_IDEDMA_AUTO is not set
@@ -272,7 +457,9 @@ CONFIG_IDE_SH=y
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=m
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -284,6 +471,7 @@ CONFIG_BLK_DEV_SD=m
 CONFIG_BLK_DEV_SR=m
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -293,15 +481,18 @@ CONFIG_CHR_DEV_SG=m
 # CONFIG_SCSI_LOGGING is not set
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
 #
+# CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
@@ -309,39 +500,34 @@ CONFIG_CHR_DEV_SG=m
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_CPQFCTS is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=m
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
 #
 # Multi-device support (RAID and LVM)
 #
@@ -351,6 +537,9 @@ CONFIG_SCSI_QLA2XXX=m
 # Fusion MPT device support
 #
 # CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -363,73 +552,8 @@ CONFIG_SCSI_QLA2XXX=m
 # CONFIG_I2O is not set
 
 #
-# Networking support
+# Network device support
 #
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
@@ -441,6 +565,11 @@ CONFIG_NETDEVICES=y
 #
 # CONFIG_ARCNET is not set
 
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
 #
 # Ethernet (10 or 100Mbit)
 #
@@ -449,6 +578,7 @@ CONFIG_MII=y
 # CONFIG_STNIC is not set
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
 
@@ -487,15 +617,22 @@ CONFIG_8139CP=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
 #
+# CONFIG_CHELSIO_T1 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
 
 #
 # Token Ring devices
@@ -518,6 +655,8 @@ CONFIG_8139CP=y
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -533,6 +672,7 @@ CONFIG_8139CP=y
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -546,14 +686,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
 #
 # Input Device Drivers
 #
@@ -563,28 +695,39 @@ CONFIG_SOUND_GAMEPORT=y
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
 #
 # Character devices
 #
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
 # Serial drivers
 #
 CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250_PCI=m
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -605,14 +748,14 @@ CONFIG_WATCHDOG=y
 #
 # CONFIG_SOFT_WATCHDOG is not set
 CONFIG_SH_WDT=m
+# CONFIG_SH_WDT_MMAP is not set
 
 #
 # PCI-based Watchdog Cards
 #
 # CONFIG_PCIPCWATCHDOG is not set
 # CONFIG_WDTPCI is not set
-# CONFIG_RTC is not set
-CONFIG_SH03_RTC=y
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -624,15 +767,36 @@ CONFIG_SH03_RTC=y
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
 #
 # I2C support
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -642,6 +806,7 @@ CONFIG_SH03_RTC=y
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -651,13 +816,14 @@ CONFIG_SH03_RTC=y
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
 
 #
 # Console display driver support
 #
-# CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -667,12 +833,13 @@ CONFIG_DUMMY_CONSOLE=y
 #
 # USB support
 #
-# CONFIG_USB is not set
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
 #
@@ -685,11 +852,46 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 #
 # CONFIG_MMC is not set
 
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
 #
 # InfiniBand support
 #
 # CONFIG_INFINIBAND is not set
 
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
 #
 # File systems
 #
@@ -697,6 +899,7 @@ CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 # CONFIG_EXT2_FS_POSIX_ACL is not set
 # CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
@@ -707,17 +910,17 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
-
-#
-# XFS support
-#
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 CONFIG_AUTOFS_FS=y
 CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -744,14 +947,14 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -775,16 +978,19 @@ CONFIG_RAMFS=y
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
 # CONFIG_NFS_DIRECTIO is not set
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
 CONFIG_NFSD_TCP=y
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
@@ -794,6 +1000,7 @@ CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
 
 #
 # Partition Types
@@ -813,6 +1020,7 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 
 #
@@ -868,9 +1076,14 @@ CONFIG_OPROFILE=m
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_PREEMPT=y
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
 CONFIG_SH_STANDARD_BIOS=y
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_EARLY_PRINTK is not set
@@ -886,6 +1099,10 @@ CONFIG_SH_STANDARD_BIOS=y
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=m
 CONFIG_CRYPTO_HMAC=y
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
@@ -894,6 +1111,9 @@ CONFIG_CRYPTO_SHA1=y
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
@@ -918,7 +1138,9 @@ CONFIG_CRYPTO_DEFLATE=y
 # Library routines
 #
 CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
index ec9a3034daa5e2936f1884d61c40c49b614a9063..9380c321169a747d19a993bc52a51776591a1f84 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.17
-# Mon Aug  7 17:07:06 2006
+# Linux kernel version: 2.6.18
+# Tue Oct  3 12:48:56 2006
 #
 CONFIG_SUPERH=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
@@ -10,6 +10,7 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
@@ -25,16 +26,20 @@ CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -46,10 +51,10 @@ CONFIG_BASE_FULL=y
 # CONFIG_EPOLL is not set
 # CONFIG_SHMEM is not set
 CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
-CONFIG_OBSOLETE_INTERMODULE=y
 
 #
 # Loadable module support
@@ -64,6 +69,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -87,6 +93,7 @@ CONFIG_DEFAULT_IOSCHED="deadline"
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
 # CONFIG_SH_HP6XX is not set
@@ -150,10 +157,15 @@ CONFIG_CPU_SUBTYPE_SH7710=y
 #
 # SH-4A Processor Support
 #
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
 #
 # Memory management options
 #
@@ -161,6 +173,7 @@ CONFIG_MMU=y
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x00800000
+CONFIG_VSYSCALL=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -169,6 +182,7 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
 
 #
 # Cache configuration
@@ -216,10 +230,10 @@ CONFIG_HZ_250=y
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
 # CONFIG_KEXEC is not set
-# CONFIG_PREEMPT is not set
 # CONFIG_SMP is not set
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
 
 #
 # Boot options
@@ -267,6 +281,9 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -282,9 +299,12 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
 # CONFIG_INET_DIAG is not set
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 
 #
 # IP: Virtual Server Configuration
@@ -293,6 +313,7 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
 
@@ -317,6 +338,7 @@ CONFIG_IP_NF_FTP=m
 # CONFIG_IP_NF_AMANDA is not set
 CONFIG_IP_NF_PPTP=m
 # CONFIG_IP_NF_H323 is not set
+# CONFIG_IP_NF_SIP is not set
 # CONFIG_IP_NF_QUEUE is not set
 
 #
@@ -342,7 +364,6 @@ CONFIG_IP_NF_PPTP=m
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -409,6 +430,7 @@ CONFIG_NET_ESTIMATOR=y
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
 
 #
 # Connector - unified userspace <-> kernelspace linker
@@ -434,6 +456,7 @@ CONFIG_MTD_BLOCK=y
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -466,8 +489,6 @@ CONFIG_MTD_RAM=y
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 # CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_SOLUTIONENGINE is not set
-CONFIG_MTD_SH7710VOIPGW=y
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -525,6 +546,12 @@ CONFIG_MTD_SH7710VOIPGW=y
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -565,7 +592,6 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
 # CONFIG_STNIC is not set
 # CONFIG_SMC91X is not set
-# CONFIG_NE2000 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -610,6 +636,7 @@ CONFIG_PHONE=y
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -667,7 +694,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -697,7 +724,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -723,7 +749,9 @@ CONFIG_VIDEO_V4L2=y
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -777,6 +805,19 @@ CONFIG_VIDEO_V4L2=y
 #
 # CONFIG_RTC_CLASS is not set
 
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
 #
 # File systems
 #
@@ -814,8 +855,10 @@ CONFIG_VIDEO_V4L2=y
 #
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
@@ -836,6 +879,7 @@ CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
 # CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
@@ -879,7 +923,9 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DEBUG_BUGVERBOSE is not set
@@ -898,10 +944,6 @@ CONFIG_LOG_BUF_SHIFT=14
 #
 # CONFIG_CRYPTO is not set
 
-#
-# Hardware crypto devices
-#
-
 #
 # Library routines
 #
index 382b3bd3963bc171a7b0286bc3f8ece6dffef330..8800fefcbaf028075a913dc82559f9864285a24a 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.17
-# Wed Aug  2 01:45:03 2006
+# Linux kernel version: 2.6.18
+# Tue Oct  3 12:52:49 2006
 #
 CONFIG_SUPERH=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
@@ -10,7 +10,7 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_PTRACE=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
@@ -28,14 +28,17 @@ CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_SYSVIPC is not set
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_UID16 is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+# CONFIG_UID16 is not set
+# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_KALLSYMS is not set
 # CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
@@ -46,10 +49,10 @@ CONFIG_PRINTK=y
 # CONFIG_EPOLL is not set
 # CONFIG_SHMEM is not set
 # CONFIG_SLAB is not set
+CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=1
 CONFIG_SLOB=y
-CONFIG_OBSOLETE_INTERMODULE=y
 
 #
 # Loadable module support
@@ -59,6 +62,7 @@ CONFIG_OBSOLETE_INTERMODULE=y
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_LSF is not set
 
@@ -79,27 +83,21 @@ CONFIG_DEFAULT_IOSCHED="noop"
 # System type
 #
 # CONFIG_SH_SOLUTION_ENGINE is not set
-# CONFIG_SH_7709_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
 # CONFIG_SH_HP6XX is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
 # CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
@@ -128,6 +126,7 @@ CONFIG_CPU_SUBTYPE_SH7706=y
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
 
 #
 # SH-4 Processor Support
@@ -150,10 +149,15 @@ CONFIG_CPU_SUBTYPE_SH7706=y
 #
 # SH-4A Processor Support
 #
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
 #
 # Memory management options
 #
@@ -161,6 +165,7 @@ CONFIG_MMU=y
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x00800000
+CONFIG_VSYSCALL=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -169,6 +174,7 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
 
 #
 # Cache configuration
@@ -211,9 +217,15 @@ CONFIG_SH_PCLK_FREQ=32000000
 #
 # Kernel features
 #
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
 # CONFIG_KEXEC is not set
-# CONFIG_PREEMPT is not set
 # CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
 
 #
 # Boot options
@@ -232,7 +244,6 @@ CONFIG_CMDLINE="console=ttySC1,115200 root=1f01 mtdparts=phys_mapped_flash:64k(f
 #
 # PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCCARD is not set
 
 #
 # PCI Hotplug Support
@@ -261,6 +272,9 @@ CONFIG_NET=y
 # CONFIG_NETDEBUG is not set
 # CONFIG_PACKET is not set
 CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -279,13 +293,17 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 
 #
@@ -311,7 +329,6 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -338,7 +355,7 @@ CONFIG_TCP_CONG_BIC=y
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
 
 #
 # Connector - unified userspace <-> kernelspace linker
@@ -364,11 +381,12 @@ CONFIG_MTD_BLOCK=y
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
 #
-# CONFIG_MTD_CFI is not set
+CONFIG_MTD_CFI=y
 CONFIG_MTD_JEDECPROBE=y
 CONFIG_MTD_GEN_PROBE=y
 # CONFIG_MTD_CFI_ADV_OPTIONS is not set
@@ -457,6 +475,12 @@ CONFIG_BLK_DEV_LOOP=y
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -497,7 +521,6 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
 # CONFIG_STNIC is not set
 # CONFIG_SMC91X is not set
-CONFIG_NE2000=y
 
 #
 # Ethernet (1000 Mbit)
@@ -580,7 +603,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -610,7 +633,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -636,6 +658,7 @@ CONFIG_VIDEO_V4L2=y
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
 
 #
@@ -690,6 +713,19 @@ CONFIG_VIDEO_V4L2=y
 #
 # CONFIG_RTC_CLASS is not set
 
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
 #
 # File systems
 #
@@ -699,7 +735,6 @@ CONFIG_VIDEO_V4L2=y
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
-# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 # CONFIG_INOTIFY is not set
@@ -727,8 +762,10 @@ CONFIG_VIDEO_V4L2=y
 #
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
 # CONFIG_SYSFS is not set
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
@@ -795,7 +832,9 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_UNWIND_INFO is not set
@@ -813,10 +852,6 @@ CONFIG_EARLY_PRINTK=y
 #
 # CONFIG_CRYPTO is not set
 
-#
-# Hardware crypto devices
-#
-
 #
 # Library routines
 #
index 69cf02a24761f16ef4f759e7512e12447c6a9a3a..98503f16f3f5da1749c0632d4e0ce70f7d02fdc2 100644 (file)
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar  2 15:09:51 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 12:55:47 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 # CONFIG_SYSVIPC is not set
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
-# CONFIG_EMBEDDED is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
 #
 # CONFIG_MODULES is not set
 
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
 #
 # System type
 #
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 CONFIG_SH_SECUREEDGE5410=y
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
+
+#
+# Processor selection
+#
 CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
 CONFIG_CPU_SUBTYPE_SH7751=y
+CONFIG_CPU_SUBTYPE_SH7751R=y
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_ST40STB1 is not set
 # CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
 CONFIG_MMU=y
-# CONFIG_CMDLINE_BOOL is not set
+CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x01000000
-CONFIG_MEMORY_SET=y
-# CONFIG_MEMORY_OVERRIDE is not set
-CONFIG_SH_RTC=y
-CONFIG_SH_FPU=y
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_PREEMPT is not set
-# CONFIG_UBC_WAKEUP is not set
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_SH_WRITETHROUGH is not set
 # CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
 # CONFIG_SH_STORE_QUEUES is not set
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
-CONFIG_SH_PCLK_FREQ=60013568
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_PCLK_FREQ=60000000
 
 #
 # CPU Frequency scaling
@@ -133,28 +220,42 @@ CONFIG_NR_ONCHIP_DMA_CHANNELS=4
 # CONFIG_HD6446X_SERIES is not set
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Bus options
 #
 CONFIG_PCI=y
 # CONFIG_SH_PCIDMA_NONCOHERENT is not set
 CONFIG_PCI_AUTO=y
 CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-# CONFIG_PCI_LEGACY_PROC is not set
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCCARD is not set
-
-#
-# PC-card bridges
-#
 
 #
 # PCI Hotplug Support
 #
-# CONFIG_HOTPLUG_PCI is not set
 
 #
 # Executable file formats
@@ -164,9 +265,94 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 
 #
-# SH initrd options
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+# CONFIG_PACKET is not set
+# CONFIG_UNIX is not set
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
 #
-# CONFIG_EMBEDDED_RAMDISK is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
 
 #
 # Device Drivers
@@ -177,7 +363,12 @@ CONFIG_BINFMT_ELF=y
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -196,7 +387,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
@@ -208,18 +398,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -230,7 +411,14 @@ CONFIG_IOSCHED_CFQ=y
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -240,6 +428,7 @@ CONFIG_IOSCHED_CFQ=y
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -252,69 +441,8 @@ CONFIG_IOSCHED_CFQ=y
 # CONFIG_I2O is not set
 
 #
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK_DEV is not set
-# CONFIG_UNIX is not set
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
+# Network device support
 #
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
@@ -326,6 +454,11 @@ CONFIG_NETDEVICES=y
 #
 # CONFIG_ARCNET is not set
 
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
 #
 # Ethernet (10 or 100Mbit)
 #
@@ -334,6 +467,7 @@ CONFIG_MII=y
 # CONFIG_STNIC is not set
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
 
@@ -376,15 +510,22 @@ CONFIG_8139TOO=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
 #
+# CONFIG_CHELSIO_T1 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
 
 #
 # Token Ring devices
@@ -406,6 +547,8 @@ CONFIG_8139TOO=y
 # CONFIG_SLIP is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -421,6 +564,7 @@ CONFIG_8139TOO=y
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -434,18 +578,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
 #
 # Input Device Drivers
 #
@@ -455,12 +587,24 @@ CONFIG_SERIO_SERPORT=y
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
 #
 # Character devices
 #
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -472,6 +616,7 @@ CONFIG_HW_CONSOLE=y
 # Non-8250 serial port support
 #
 # CONFIG_SERIAL_SH_SCI is not set
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -485,7 +630,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -497,15 +642,36 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
 #
 # I2C support
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -515,6 +681,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -524,13 +691,14 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
 
 #
 # Console display driver support
 #
-CONFIG_VGA_CONSOLE=y
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -540,12 +708,13 @@ CONFIG_DUMMY_CONSOLE=y
 #
 # USB support
 #
-# CONFIG_USB is not set
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
 #
@@ -558,31 +727,67 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 #
 # CONFIG_MMC is not set
 
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
 #
 # InfiniBand support
 #
 # CONFIG_INFINIBAND is not set
 
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -602,16 +807,14 @@ CONFIG_DNOTIFY=y
 #
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -635,12 +838,14 @@ CONFIG_CRAMFS=y
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -649,6 +854,7 @@ CONFIG_SUNRPC=y
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
 
 #
 # Partition Types
@@ -669,8 +875,15 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_UNWIND_INFO is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_KGDB is not set
@@ -686,14 +899,12 @@ CONFIG_MSDOS_PARTITION=y
 #
 # CONFIG_CRYPTO is not set
 
-#
-# Hardware crypto devices
-#
-
 #
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
index 431c9c9da165348338741f9e4b0a0cbbb0c1ff56..c16350dac01bf8ebc854566d9e937ff888201126 100644 (file)
@@ -1,48 +1,58 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar  2 15:09:53 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 12:57:29 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-# CONFIG_CLEAN_COMPILE is not set
-CONFIG_BROKEN=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -50,75 +60,150 @@ CONFIG_CC_ALIGN_JUMPS=0
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 # CONFIG_KMOD is not set
 
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
 #
 # System type
 #
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 CONFIG_SH_7751_SYSTEMH=y
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
+# CONFIG_SH_HP6XX is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
+
+#
+# Processor selection
+#
 CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
 CONFIG_CPU_SUBTYPE_SH7751=y
+CONFIG_CPU_SUBTYPE_SH7751R=y
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_ST40STB1 is not set
 # CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
 CONFIG_MMU=y
-# CONFIG_CMDLINE_BOOL is not set
+CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x00400000
-# CONFIG_MEMORY_OVERRIDE is not set
-CONFIG_SH_RTC=y
-CONFIG_SH_FPU=y
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_PREEMPT=y
-# CONFIG_UBC_WAKEUP is not set
+CONFIG_VSYSCALL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_SH_WRITETHROUGH is not set
 # CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
 # CONFIG_SH_STORE_QUEUES is not set
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
-CONFIG_SH_PCLK_FREQ=49876504
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_PCLK_FREQ=60000000
 
 #
 # CPU Frequency scaling
@@ -136,28 +221,39 @@ CONFIG_SH_PCLK_FREQ=49876504
 # CONFIG_HD6446X_SERIES is not set
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
 #
-CONFIG_PCI=y
-# CONFIG_SH_PCIDMA_NONCOHERENT is not set
-CONFIG_PCI_AUTO=y
-CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
 
 #
-# PCCARD (PCMCIA/CardBus) support
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Bus options
 #
-# CONFIG_PCCARD is not set
+# CONFIG_PCI is not set
 
 #
-# PC-card bridges
+# PCCARD (PCMCIA/CardBus) support
 #
 
 #
 # PCI Hotplug Support
 #
-# CONFIG_HOTPLUG_PCI is not set
 
 #
 # Executable file formats
@@ -167,9 +263,14 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 
 #
-# SH initrd options
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
 #
-# CONFIG_EMBEDDED_RAMDISK is not set
+# CONFIG_NET is not set
 
 #
 # Device Drivers
@@ -180,7 +281,11 @@ CONFIG_BINFMT_ELF=y
 #
 # CONFIG_STANDALONE is not set
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
 
 #
 # Memory Technology Devices (MTD)
@@ -199,30 +304,15 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=1024
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
 
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-
 #
 # ATA/ATAPI/MFM/RLL support
 #
@@ -231,7 +321,14 @@ CONFIG_IOSCHED_CFQ=y
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -241,23 +338,15 @@ CONFIG_IOSCHED_CFQ=y
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
 #
-# CONFIG_IEEE1394 is not set
 
 #
 # I2O device support
 #
-# CONFIG_I2O is not set
-
-#
-# Networking support
-#
-# CONFIG_NET is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -274,25 +363,14 @@ CONFIG_IOSCHED_CFQ=y
 # CONFIG_INPUT is not set
 
 #
-# Userland interfaces
-#
-
+# Hardware I/O ports
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 CONFIG_SERIO=y
 # CONFIG_SERIO_I8042 is not set
 # CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
 # CONFIG_SERIO_LIBPS2 is not set
 # CONFIG_SERIO_RAW is not set
-
-#
-# Input Device Drivers
-#
+# CONFIG_GAMEPORT is not set
 
 #
 # Character devices
@@ -322,27 +400,46 @@ CONFIG_LEGACY_PTY_COUNT=256
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
 
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
 #
 # I2C support
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -352,6 +449,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -360,7 +458,9 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -370,12 +470,12 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # USB support
 #
-# CONFIG_USB is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
 #
@@ -388,30 +488,63 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 #
 # CONFIG_MMC is not set
 
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
 #
 # InfiniBand support
 #
-# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
 
 #
 # File systems
 #
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -431,16 +564,14 @@ CONFIG_DNOTIFY=y
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -478,9 +609,14 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_PREEMPT=y
-# CONFIG_FRAME_POINTER is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_KGDB is not set
@@ -496,14 +632,12 @@ CONFIG_DEBUG_PREEMPT=y
 #
 # CONFIG_CRYPTO is not set
 
-#
-# Hardware crypto devices
-#
-
 #
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
index 1db2904de9e5ab80a1af9e01db3aebada96bbc97..5e817546113893289a6ccfdf3d1da879690ed8e6 100644 (file)
@@ -1,21 +1,21 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14-sh
-# Wed Nov  9 00:35:56 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 12:59:14 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 
@@ -26,31 +26,38 @@ CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_IPC_NS is not set
+CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+# CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_EMBEDDED is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -58,40 +65,57 @@ CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
 #
 # System type
 #
 # CONFIG_SH_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SOLUTION_ENGINE is not set
 # CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
 # CONFIG_SH_73180_SOLUTION_ENGINE is not set
 # CONFIG_SH_7751_SYSTEMH is not set
-CONFIG_SH_TITAN=y
-# CONFIG_SH_STB1_HARP is not set
-# CONFIG_SH_STB1_OVERDRIVE is not set
 # CONFIG_SH_HP6XX is not set
-# CONFIG_SH_CQREEK is not set
-# CONFIG_SH_DMIDA is not set
 # CONFIG_SH_EC3104 is not set
 # CONFIG_SH_SATURN is not set
 # CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_CAT68701 is not set
 # CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_SH2000 is not set
-# CONFIG_SH_ADX is not set
 # CONFIG_SH_MPC1211 is not set
 # CONFIG_SH_SH03 is not set
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
 # CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 # CONFIG_SH_SH4202_MICRODEV is not set
 # CONFIG_SH_LANDISK is not set
+CONFIG_SH_TITAN=y
+# CONFIG_SH_SHMIN is not set
 # CONFIG_SH_UNKNOWN is not set
 
 #
@@ -109,9 +133,11 @@ CONFIG_CPU_SH4=y
 #
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
 
 #
 # SH-4 Processor Support
@@ -134,14 +160,23 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
 #
 # SH-4A Processor Support
 #
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
 #
 # Memory management options
 #
 CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x08030000
+CONFIG_MEMORY_SIZE=0x7fd0000
+CONFIG_VSYSCALL=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -149,6 +184,8 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
 
 #
 # Cache configuration
@@ -156,22 +193,21 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_SH_WRITETHROUGH is not set
 # CONFIG_SH_OCRAM is not set
-CONFIG_MEMORY_START=0x08030000
-CONFIG_MEMORY_SIZE=0x7fd0000
 
 #
 # Processor features
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_SH_RTC=y
 CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
 # CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
 
 #
 # Timer support
 #
 CONFIG_SH_TMU=y
-CONFIG_SH_PCLK_FREQ_BOOL=y
 CONFIG_SH_PCLK_FREQ=30000000
 
 #
@@ -194,9 +230,15 @@ CONFIG_NR_ONCHIP_DMA_CHANNELS=8
 #
 # Kernel features
 #
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
 # CONFIG_KEXEC is not set
-# CONFIG_PREEMPT is not set
 # CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
 
 #
 # Boot options
@@ -214,8 +256,8 @@ CONFIG_PCI=y
 CONFIG_SH_PCIDMA_NONCOHERENT=y
 CONFIG_PCI_AUTO=y
 CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-CONFIG_PCI_LEGACY_PROC=y
-#CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -237,6 +279,11 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_FLAT is not set
 # CONFIG_BINFMT_MISC is not set
 
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
 #
 # Networking
 #
@@ -245,11 +292,13 @@ CONFIG_NET=y
 #
 # Networking options
 #
+# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_NET_KEY=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -270,40 +319,87 @@ CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 CONFIG_IP_PNP_RARP=y
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
+CONFIG_NET_IPIP=y
+CONFIG_NET_IPGRE=y
 CONFIG_NET_IPGRE_BROADCAST=y
 CONFIG_IP_MROUTE=y
 CONFIG_IP_PIMSM_V1=y
 CONFIG_IP_PIMSM_V2=y
 # CONFIG_ARPD is not set
 CONFIG_SYN_COOKIES=y
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-CONFIG_INET_TUNNEL=m
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_DIAG=m
 CONFIG_INET_TCP_DIAG=m
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 
 #
 # IP: Virtual Server Configuration
 #
 # CONFIG_IP_VS is not set
-CONFIG_IPV6=m
+CONFIG_IPV6=y
 CONFIG_IPV6_PRIVACY=y
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_INET6_TUNNEL=m
-CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_ROUTER_PREF is not set
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=y
+CONFIG_INET6_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_TUNNEL=y
+# CONFIG_IPV6_SUBTREES is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
 CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
 CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 
 #
 # IP: Netfilter Configuration
@@ -320,42 +416,24 @@ CONFIG_IP_NF_NETBIOS_NS=m
 CONFIG_IP_NF_TFTP=m
 # CONFIG_IP_NF_AMANDA is not set
 CONFIG_IP_NF_PPTP=m
+CONFIG_IP_NF_H323=m
+# CONFIG_IP_NF_SIP is not set
 CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
 CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
 CONFIG_IP_NF_MATCH_TOS=m
 CONFIG_IP_NF_MATCH_RECENT=m
 CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_AH=m
 CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
 CONFIG_IP_NF_MATCH_OWNER=m
-# CONFIG_IP_NF_MATCH_PHYSDEV is not set
 CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_REALM=m
-# CONFIG_IP_NF_MATCH_SCTP is not set
-# CONFIG_IP_NF_MATCH_DCCP is not set
-CONFIG_IP_NF_MATCH_COMMENT=m
-CONFIG_IP_NF_MATCH_CONNMARK=m
-CONFIG_IP_NF_MATCH_CONNBYTES=m
 CONFIG_IP_NF_MATCH_HASHLIMIT=m
-CONFIG_IP_NF_MATCH_STRING=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
 CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
 CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_TARGET_NFQUEUE=m
 CONFIG_IP_NF_NAT=m
 CONFIG_IP_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
@@ -367,17 +445,13 @@ CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
 CONFIG_IP_NF_NAT_TFTP=m
 CONFIG_IP_NF_NAT_PPTP=m
+CONFIG_IP_NF_NAT_H323=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_TOS=m
 CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_CLASSIFY=m
 CONFIG_IP_NF_TARGET_TTL=m
-CONFIG_IP_NF_TARGET_CONNMARK=m
 CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_TARGET_NOTRACK=m
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
@@ -387,26 +461,18 @@ CONFIG_IP_NF_ARP_MANGLE=m
 #
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
 CONFIG_IP6_NF_MATCH_RT=m
 CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_FRAG=m
 CONFIG_IP6_NF_MATCH_HL=m
-CONFIG_IP6_NF_MATCH_MULTIPORT=m
 CONFIG_IP6_NF_MATCH_OWNER=m
-CONFIG_IP6_NF_MATCH_MARK=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_MATCH_AHESP=m
-CONFIG_IP6_NF_MATCH_LENGTH=m
+CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
-# CONFIG_IP6_NF_MATCH_PHYSDEV is not set
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_TARGET_REJECT=m
-CONFIG_IP6_NF_TARGET_NFQUEUE=m
 CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
 CONFIG_IP6_NF_TARGET_HL=m
 CONFIG_IP6_NF_RAW=m
 
@@ -424,22 +490,35 @@ CONFIG_IP6_NF_RAW=m
 # SCTP Configuration (EXPERIMENTAL)
 #
 # CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_ATM is not set
-CONFIG_BRIDGE=m
-CONFIG_VLAN_8021Q=m
+CONFIG_BRIDGE=y
+CONFIG_VLAN_8021Q=y
 # CONFIG_DECNET is not set
+CONFIG_LLC=y
 # CONFIG_LLC2 is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
 CONFIG_NET_SCHED=y
 CONFIG_NET_SCH_CLK_JIFFIES=y
 # CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
 # CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
 CONFIG_NET_SCH_CBQ=m
 CONFIG_NET_SCH_HTB=m
 CONFIG_NET_SCH_HFSC=m
@@ -452,8 +531,10 @@ CONFIG_NET_SCH_GRED=m
 CONFIG_NET_SCH_DSMARK=m
 CONFIG_NET_SCH_NETEM=m
 CONFIG_NET_SCH_INGRESS=m
-CONFIG_NET_QOS=y
-CONFIG_NET_ESTIMATOR=y
+
+#
+# Classification
+#
 CONFIG_NET_CLS=y
 CONFIG_NET_CLS_BASIC=m
 CONFIG_NET_CLS_TCINDEX=m
@@ -462,7 +543,6 @@ CONFIG_NET_CLS_ROUTE=y
 CONFIG_NET_CLS_FW=m
 CONFIG_NET_CLS_U32=m
 CONFIG_CLS_U32_PERF=y
-CONFIG_NET_CLS_IND=y
 CONFIG_CLS_U32_MARK=y
 CONFIG_NET_CLS_RSVP=m
 CONFIG_NET_CLS_RSVP6=m
@@ -481,6 +561,8 @@ CONFIG_NET_ACT_MIRRED=m
 CONFIG_NET_ACT_IPT=m
 CONFIG_NET_ACT_PEDIT=m
 # CONFIG_NET_ACT_SIMP is not set
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
 
 #
 # Network testing
@@ -489,7 +571,15 @@ CONFIG_NET_ACT_PEDIT=m
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-# CONFIG_IEEE80211 is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=y
+CONFIG_IEEE80211_CRYPT_TKIP=y
+CONFIG_IEEE80211_SOFTMAC=m
+# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
+CONFIG_WIRELESS_EXT=y
+CONFIG_FIB_RULES=y
 
 #
 # Device Drivers
@@ -502,6 +592,7 @@ CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=m
 # CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
 
 #
 # Connector - unified userspace <-> kernelspace linker
@@ -511,7 +602,86 @@ CONFIG_CONNECTOR=m
 #
 # Memory Technology Devices (MTD)
 #
-# CONFIG_MTD is not set
+CONFIG_MTD=m
+CONFIG_MTD_DEBUG=y
+CONFIG_MTD_DEBUG_VERBOSE=0
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_PARTITIONS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+# CONFIG_MTD_BLOCK_RO is not set
+CONFIG_FTL=m
+CONFIG_NFTL=m
+# CONFIG_NFTL_RW is not set
+CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
+# CONFIG_SSFDC is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND_IDS=m
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
 
 #
 # Parallel port support
@@ -528,29 +698,20 @@ CONFIG_CONNECTOR=m
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
-CONFIG_BLK_SSFDC=y
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=m
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_CRYPTOLOOP=m
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_ATA_OVER_ETH is not set
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -561,7 +722,8 @@ CONFIG_IOSCHED_CFQ=y
 # SCSI device support
 #
 # CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=m
+CONFIG_SCSI=y
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -583,16 +745,18 @@ CONFIG_CHR_DEV_SG=m
 # CONFIG_SCSI_LOGGING is not set
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
 # CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
 #
+# CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
@@ -600,33 +764,34 @@ CONFIG_CHR_DEV_SG=m
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=m
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_QLA_FC is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
 #
 # Multi-device support (RAID and LVM)
 #
@@ -654,6 +819,7 @@ CONFIG_SCSI_QLA2XXX=m
 # Network device support
 #
 CONFIG_NETDEVICES=y
+# CONFIG_IFB is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
@@ -668,7 +834,6 @@ CONFIG_TUN=m
 # PHY device support
 #
 CONFIG_PHYLIB=m
-CONFIG_PHYCONTROL=y
 
 #
 # MII PHY device drivers
@@ -678,6 +843,9 @@ CONFIG_DAVICOM_PHY=m
 CONFIG_QSEMI_PHY=m
 CONFIG_LXT_PHY=m
 CONFIG_CICADA_PHY=m
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -687,7 +855,7 @@ CONFIG_MII=y
 # CONFIG_STNIC is not set
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
-CONFIG_CASSINI=m
+# CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
 
@@ -696,7 +864,6 @@ CONFIG_CASSINI=m
 #
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
-# CONFIG_NE2000 is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
@@ -733,10 +900,12 @@ CONFIG_8139_OLD_RX_RESET=y
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -744,6 +913,7 @@ CONFIG_8139_OLD_RX_RESET=y
 # CONFIG_CHELSIO_T1 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
 
 #
 # Token Ring devices
@@ -754,6 +924,7 @@ CONFIG_8139_OLD_RX_RESET=y
 # Wireless LAN (non-hamradio)
 #
 CONFIG_NET_RADIO=y
+CONFIG_NET_WIRELESS_RTNETLINK=y
 
 #
 # Obsolete Wireless cards support (pre-802.11)
@@ -763,6 +934,8 @@ CONFIG_NET_RADIO=y
 #
 # Wireless 802.11b ISA/PCI cards support
 #
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
 # CONFIG_HERMES is not set
 # CONFIG_ATMEL is not set
 
@@ -770,7 +943,16 @@ CONFIG_NET_RADIO=y
 # Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
 #
 CONFIG_PRISM54=m
+# CONFIG_USB_ZD1201 is not set
 # CONFIG_HOSTAP is not set
+CONFIG_BCM43XX=m
+CONFIG_BCM43XX_DEBUG=y
+CONFIG_BCM43XX_DMA=y
+CONFIG_BCM43XX_PIO=y
+CONFIG_BCM43XX_DMA_AND_PIO_MODE=y
+# CONFIG_BCM43XX_DMA_MODE is not set
+# CONFIG_BCM43XX_PIO_MODE is not set
+# CONFIG_ZD1211RW is not set
 CONFIG_NET_WIRELESS=y
 
 #
@@ -786,8 +968,13 @@ CONFIG_PPP_ASYNC=m
 CONFIG_PPP_SYNC_TTY=m
 CONFIG_PPP_DEFLATE=m
 CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
-# CONFIG_SLIP is not set
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLHC=m
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
@@ -808,6 +995,7 @@ CONFIG_PPPOE=m
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -842,6 +1030,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -853,6 +1042,7 @@ CONFIG_HW_CONSOLE=y
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -869,8 +1059,27 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # Watchdog Cards
 #
-# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_SH_WDT=m
+# CONFIG_SH_WDT_MMAP is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -886,12 +1095,19 @@ CONFIG_LEGACY_PTY_COUNT=256
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -902,35 +1118,38 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
 #
 
-#
-# Multimedia Capabilities Port drivers
-#
-
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
 #
 # CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
 
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
 
 #
 # Console display driver support
 #
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -942,7 +1161,8 @@ CONFIG_DUMMY_CONSOLE=y
 #
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB=m
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
 #
@@ -956,11 +1176,12 @@ CONFIG_USB_DEVICEFS=y
 #
 # USB Host Controller Drivers
 #
-CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
 # CONFIG_USB_ISP116X_HCD is not set
-CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_UHCI_HCD is not set
@@ -969,14 +1190,17 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 #
 # USB Device Class drivers
 #
-# CONFIG_USB_BLUETOOTH_TTY is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
-CONFIG_USB_STORAGE=m
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
@@ -985,6 +1209,9 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
 
 #
 # USB Input Devices
@@ -1001,14 +1228,14 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_ACECAD is not set
 # CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_ITMTOUCH is not set
-# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_TOUCHSCREEN is not set
 # CONFIG_USB_YEALINK is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 
 #
 # USB Imaging devices
@@ -1016,15 +1243,6 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
 
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
 #
 # USB Network Adapters
 #
@@ -1033,7 +1251,6 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
-# CONFIG_USB_ZD1201 is not set
 CONFIG_USB_MON=y
 
 #
@@ -1045,7 +1262,9 @@ CONFIG_USB_MON=y
 #
 CONFIG_USB_SERIAL=m
 CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRCABLE is not set
 # CONFIG_USB_SERIAL_AIRPRIME is not set
+CONFIG_USB_SERIAL_ARK3116=m
 # CONFIG_USB_SERIAL_BELKIN is not set
 # CONFIG_USB_SERIAL_WHITEHEAT is not set
 # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
@@ -1053,6 +1272,7 @@ CONFIG_USB_SERIAL_GENERIC=y
 # CONFIG_USB_SERIAL_CYPRESS_M8 is not set
 # CONFIG_USB_SERIAL_EMPEG is not set
 # CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
 # CONFIG_USB_SERIAL_VISOR is not set
 # CONFIG_USB_SERIAL_IPAQ is not set
 # CONFIG_USB_SERIAL_IR is not set
@@ -1065,12 +1285,16 @@ CONFIG_USB_SERIAL_GENERIC=y
 # CONFIG_USB_SERIAL_KLSI is not set
 # CONFIG_USB_SERIAL_KOBIL_SCT is not set
 # CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
 CONFIG_USB_SERIAL_PL2303=m
 # CONFIG_USB_SERIAL_HP4X is not set
 # CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
 # CONFIG_USB_SERIAL_TI is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
 # CONFIG_USB_SERIAL_OMNINET is not set
 
 #
@@ -1078,15 +1302,18 @@ CONFIG_USB_SERIAL_PL2303=m
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
 # CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
 # CONFIG_USB_TEST is not set
@@ -1105,40 +1332,72 @@ CONFIG_USB_SERIAL_PL2303=m
 #
 # CONFIG_MMC is not set
 
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
 #
 # InfiniBand support
 #
 # CONFIG_INFINIBAND is not set
 
 #
-# SN Devices
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
 #
 
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_XATTR=y
-CONFIG_EXT3_FS_POSIX_ACL=y
-CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT3_FS_XATTR is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
 CONFIG_REISERFS_FS=m
 # CONFIG_REISERFS_CHECK is not set
 # CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_REISERFS_FS_XATTR is not set
 # CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
-# CONFIG_XFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_XFS_FS=m
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_SECURITY is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
@@ -1170,12 +1429,14 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-CONFIG_RELAYFS_FS=m
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
@@ -1187,6 +1448,8 @@ CONFIG_RELAYFS_FS=m
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_HPFS_FS is not set
@@ -1241,6 +1504,7 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 
 #
@@ -1296,21 +1560,36 @@ CONFIG_NLS_UTF8=m
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=16
 # CONFIG_DETECT_SOFTLOCKUP is not set
 # CONFIG_SCHEDSTATS is not set
-CONFIG_DEBUG_SLAB=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 # CONFIG_FRAME_POINTER is not set
+# CONFIG_FORCED_INLINING is not set
+# CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 CONFIG_EARLY_SCIF_CONSOLE=y
 # CONFIG_EARLY_PRINTK is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_4KSTACKS is not set
 # CONFIG_KGDB is not set
 
 #
@@ -1323,28 +1602,35 @@ CONFIG_EARLY_SCIF_CONSOLE=y
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=m
 CONFIG_CRYPTO_HMAC=y
-# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
-CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_AES=y
 CONFIG_CRYPTO_CAST5=m
 CONFIG_CRYPTO_CAST6=m
 CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_ARC4=y
 CONFIG_CRYPTO_KHAZAD=m
 CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
 CONFIG_CRYPTO_CRC32C=m
 # CONFIG_CRYPTO_TEST is not set
 
@@ -1359,9 +1645,10 @@ CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
 CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=m
-CONFIG_ZLIB_DEFLATE=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
 CONFIG_TEXTSEARCH=y
 CONFIG_TEXTSEARCH_KMP=m
 CONFIG_TEXTSEARCH_BM=m
 CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
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 70a5d82eb2f8c8b6a10340e152e77357304ce162..29b8ef9873d19128f27c150275e8705b2d7357c5 100644 (file)
@@ -48,12 +48,11 @@ static int __init dma_sysclass_init(void)
        int ret;
 
        ret = sysdev_class_register(&dma_sysclass);
-       if (ret == 0)
-               sysfs_create_file(&dma_sysclass.kset.kobj, &attr_devices.attr);
+       if (unlikely(ret))
+               return ret;
 
-       return ret;
+       return sysfs_create_file(&dma_sysclass.kset.kobj, &attr_devices.attr);
 }
-
 postcore_initcall(dma_sysclass_init);
 
 static ssize_t dma_show_dev_id(struct sys_device *dev, char *buf)
@@ -152,4 +151,3 @@ void dma_remove_sysfs_files(struct dma_channel *chan, struct dma_info *info)
 
        sysdev_unregister(dev);
 }
-
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 ada301c21fe7d3b489757fbe8d9a016487e6a4a4..d06030815a96acca6a01d5a54d3d41d86ef60b31 100644 (file)
@@ -8,7 +8,6 @@
  * May be copied or modified under the terms of the GNU General Public
  * License.  See linux/COPYING for more information.
  */
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/init.h>
index 554d5ed2c5865466878eae422e08ad3855125257..6e3ba9c65b40534de3d65f3c9a358d52d3476853 100644 (file)
@@ -8,8 +8,6 @@
  *
  * PCI initialization for the Renesas SH7780 Highlander R7780RP-1 board
  */
-
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/init.h>
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 e58d556e5f94b0cde1523815f6dacbdff9fdf7d6..ebb58e605d9d27ddd47fecc45ce30d3a1e11a5db 100644 (file)
@@ -35,10 +35,10 @@ static struct resource sh7751_mem_resource = {
        .flags  = IORESOURCE_MEM
 };
 
-extern struct pci_ops sh7751_pci_ops;
+extern struct pci_ops sh4_pci_ops;
 
 struct pci_channel board_pci_channels[] = {
-       { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
+       { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
        { NULL, NULL, NULL, 0, 0 },
 };
 
index c6097bcd97fd4a5b1799024c7ee881534bd93bad..cd56d53375e7dc806c32c31cd2851058a622985b 100644 (file)
@@ -11,8 +11,6 @@
  *
  * PCI initialization for the Titan boards
  */
-
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/init.h>
index bd3064a820878062904c1c9c6c20ccd2824cfb0d..d6e635296534201965be4c9ce72a806a154b3597 100644 (file)
  *  License.  See linux/COPYING for more information.
  *
  */
-
 #undef DEBUG
 
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
index 871e7d640002fa73c075457c8a39062fab155d38..4f66f91b1006671dd617c77c755b946aa727557a 100644 (file)
@@ -16,7 +16,6 @@
  * [This document is available from Microsoft at:
  *    http://www.microsoft.com/hwdev/busbios/amp_12.htm]
  */
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/poll.h>
 #include <linux/timer.h>
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 fe8221855b282648f25472cd64286814728f7843..97c571fbcdf13a5e2922867c143bf55dcb432292 100644 (file)
@@ -10,8 +10,8 @@
  * for more details.
  *
  */
-
 #include <linux/sys.h>
+#include <linux/errno.h>
 #include <linux/linkage.h>
 #include <asm/asm-offsets.h>
 #include <asm/thread_info.h>
  *     syscall #
  *
  */
-
-ENOSYS = 38
-EINVAL = 22
-
 #if defined(CONFIG_KGDB_NMI)
 NMI_VEC = 0x1c0                        ! Must catch early for debounce
 #endif
index 5f587332234a3e977cf1203477831dddfb446f50..36d86f9ac38a78b2834c6ba6551c1a6053ac76ef 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: setup.c,v 1.30 2003/10/13 07:21:19 lethal Exp $
- *
+/*
  *  linux/arch/sh/kernel/setup.c
  *
  *  Copyright (C) 1999  Niibe Yutaka
@@ -21,6 +20,7 @@
 #include <linux/utsname.h>
 #include <linux/cpu.h>
 #include <linux/pfn.h>
+#include <linux/fs.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/sections.h>
@@ -459,7 +459,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                seq_printf(m, "machine\t\t: %s\n", get_system_type());
 
        seq_printf(m, "processor\t: %d\n", cpu);
-       seq_printf(m, "cpu family\t: %s\n", system_utsname.machine);
+       seq_printf(m, "cpu family\t: %s\n", init_utsname()->machine);
        seq_printf(m, "cpu type\t: %s\n", get_cpu_subtype());
 
        show_cpuflags(m);
index d3cbfa2ad4a785b13d9e6b130ee5c435b9cbf948..9daad70bc3050bf45a86e83b25018295a164be11 100644 (file)
@@ -72,6 +72,7 @@ DECLARE_EXPORT(__ashrdi3);
 DECLARE_EXPORT(__ashldi3);
 DECLARE_EXPORT(__lshrdi3);
 DECLARE_EXPORT(__movstr);
+DECLARE_EXPORT(__movstrSI16);
 
 EXPORT_SYMBOL(strcpy);
 
index 6c0fb7c4af1190f40f1fcca3f93b2e15a82fedc9..dbebaddcfe394974686c833a39f837d562720fa5 100644 (file)
@@ -42,6 +42,7 @@ cpumask_t cpu_possible_map;
 EXPORT_SYMBOL(cpu_possible_map);
 
 cpumask_t cpu_online_map;
+EXPORT_SYMBOL(cpu_online_map);
 static atomic_t cpus_booted = ATOMIC_INIT(0);
 
 /* These are defined by the board-specific code. */
index b68ff705f0673c56c1a6845d97569689df136932..8fde95001c346873744057040b85c6f3cdbb094d 100644 (file)
@@ -25,6 +25,7 @@
 #include <asm/cacheflush.h>
 #include <asm/uaccess.h>
 #include <asm/ipc.h>
+#include <asm/unistd.h>
 
 /*
  * sys_pipe() is the normal C calling standard for creating
@@ -281,7 +282,7 @@ asmlinkage int sys_uname(struct old_utsname * name)
        if (!name)
                return -EFAULT;
        down_read(&uts_sem);
-       err=copy_to_user(name, &system_utsname, sizeof (*name));
+       err = copy_to_user(name, utsname(), sizeof (*name));
        up_read(&uts_sem);
        return err?-EFAULT:0;
 }
@@ -309,3 +310,19 @@ asmlinkage int sys_fadvise64_64_wrapper(int fd, u32 offset0, u32 offset1,
                                (u64)len0 << 32 | len1, advice);
 #endif
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+       register long __sc0 __asm__ ("r3") = __NR_execve;
+       register long __sc4 __asm__ ("r4") = (long) filename;
+       register long __sc5 __asm__ ("r5") = (long) argv;
+       register long __sc6 __asm__ ("r6") = (long) envp;
+       __asm__ __volatile__ ("trapa    #0x13" : "=z" (__sc0)
+                       : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6)
+                       : "memory");
+       return __sc0;
+}
diff --git a/arch/sh/kernel/vsyscall/.gitignore b/arch/sh/kernel/vsyscall/.gitignore
new file mode 100644 (file)
index 0000000..40836ad
--- /dev/null
@@ -0,0 +1 @@
+vsyscall.lds
index 26b6046814fdf082ca0425923177b148a69c0da6..1efbac15ff4e4d370ab3c9fa651a7ae093c09163 100644 (file)
@@ -7,7 +7,6 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  */
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/types.h>
index a22d914e4d15a1f52a8a9fba5c32894f2c81e596..e0122bd33ddb6373771e0d10bc648063ff2d990d 100644 (file)
@@ -111,7 +111,7 @@ static int cache_seq_show(struct seq_file *file, void *iter)
 
 static int cache_debugfs_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, cache_seq_show, inode->u.generic_ip);
+       return single_open(file, cache_seq_show, inode->i_private);
 }
 
 static struct file_operations cache_debugfs_fops = {
index bb2b82234e83a0610baa4b641e817773a15d9e27..65161e368353609fe58081a4fb6034aa3168a6de 100644 (file)
@@ -20,8 +20,6 @@ END   {
          printf("#ifndef __ASM_SH_MACHTYPES_H\n");
          printf("#define __ASM_SH_MACHTYPES_H\n");
          printf("\n");
-         printf("#include <linux/config.h>\n");
-         printf("\n");
          printf("/*\n");
          printf(" * We'll use the following MACH_xxx defs for placeholders for the time\n");
          printf(" * being .. these will all go away once sh_machtype is assigned per-board.\n");
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 48f27407d5e4b2c0ee10f2023e9bf27a9e092489..d81df574a7f70840ffd0121778065368ad210965 100644 (file)
@@ -1,55 +1,89 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11
-# Fri Feb 25 18:14:31 2005
+# Linux kernel version: 2.6.18
+# Tue Oct  3 13:30:51 2006
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH64=y
 CONFIG_MMU=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 # CONFIG_SYSVIPC is not set
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
 #
 # CONFIG_MODULES is not set
 
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
 #
 # System type
 #
@@ -103,25 +137,29 @@ CONFIG_HEARTBEAT=y
 CONFIG_HDSP253_LED=y
 CONFIG_SH_DMA=y
 CONFIG_PREEMPT=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
 
 #
 # Bus options (PCI, PCMCIA, EISA, MCA, ISA)
 #
-CONFIG_SUPERHYWAY=y
 CONFIG_PCI=y
 CONFIG_SH_PCIDMA_NONCOHERENT=y
-CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
 # CONFIG_PCCARD is not set
 
-#
-# PC-card bridges
-#
-
 #
 # PCI Hotplug Support
 #
@@ -134,6 +172,92 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_FLAT is not set
 # CONFIG_BINFMT_MISC is not set
 
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
 #
 # Device Drivers
 #
@@ -145,6 +269,12 @@ CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
 # CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -163,7 +293,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
@@ -176,18 +305,9 @@ CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_BLK_DEV_INITRD is not set
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -198,7 +318,9 @@ CONFIG_IOSCHED_CFQ=y
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -209,6 +331,7 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_CHR_DEV_OSST is not set
 # CONFIG_BLK_DEV_SR is not set
 # CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -218,15 +341,18 @@ CONFIG_SCSI_MULTI_LUN=y
 # CONFIG_SCSI_LOGGING is not set
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
 #
+# CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
@@ -234,39 +360,38 @@ CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 CONFIG_SCSI_SYM53C8XX_2=y
 CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+CONFIG_SCSI_SYM53C8XX_MMIO=y
 # CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
 #
 # Multi-device support (RAID and LVM)
 #
@@ -276,6 +401,9 @@ CONFIG_SCSI_QLA2XXX=y
 # Fusion MPT device support
 #
 # CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -288,70 +416,8 @@ CONFIG_SCSI_QLA2XXX=y
 # CONFIG_I2O is not set
 
 #
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
+# Network device support
 #
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
@@ -363,6 +429,11 @@ CONFIG_NETDEVICES=y
 #
 # CONFIG_ARCNET is not set
 
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
 #
 # Ethernet (10 or 100Mbit)
 #
@@ -371,7 +442,9 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_STNIC is not set
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_SMC91X is not set
 
 #
 # Tulip family network device support
@@ -385,6 +458,7 @@ CONFIG_TULIP=y
 # CONFIG_DE4X5 is not set
 # CONFIG_WINBOND_840 is not set
 # CONFIG_DM9102 is not set
+# CONFIG_ULI526X is not set
 # CONFIG_HP100 is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
@@ -416,15 +490,22 @@ CONFIG_NET_PCI=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
 #
+# CONFIG_CHELSIO_T1 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
 
 #
 # Token Ring devices
@@ -447,6 +528,8 @@ CONFIG_NET_PCI=y
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -462,6 +545,7 @@ CONFIG_NET_PCI=y
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -475,19 +559,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-
 #
 # Input Device Drivers
 #
@@ -497,6 +568,7 @@ CONFIG_KEYBOARD_ATKBD=y
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 # CONFIG_MOUSE_SERIAL is not set
@@ -505,12 +577,24 @@ CONFIG_MOUSE_PS2=y
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
 #
 # Character devices
 #
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -522,9 +606,11 @@ CONFIG_HW_CONSOLE=y
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -551,7 +637,7 @@ CONFIG_WATCHDOG=y
 #
 # CONFIG_PCIPCWATCHDOG is not set
 # CONFIG_WDTPCI is not set
-# CONFIG_RTC is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -563,15 +649,36 @@ CONFIG_WATCHDOG=y
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
 #
 # I2C support
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -581,6 +688,7 @@ CONFIG_WATCHDOG=y
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -590,7 +698,13 @@ CONFIG_WATCHDOG=y
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
 CONFIG_FB_MODE_HELPERS=y
 # CONFIG_FB_TILEBLITTING is not set
 # CONFIG_FB_CIRRUS is not set
@@ -599,9 +713,10 @@ CONFIG_FB_MODE_HELPERS=y
 # CONFIG_FB_ASILIANT is not set
 # CONFIG_FB_IMSTT is not set
 # CONFIG_FB_EPSON1355 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
 # CONFIG_FB_RIVA is not set
 # CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON_OLD is not set
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_ATY is not set
@@ -617,18 +732,20 @@ CONFIG_FB_KYRO=y
 #
 # Console display driver support
 #
-# CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
 CONFIG_FONTS=y
 # CONFIG_FONT_8x8 is not set
 CONFIG_FONT_8x16=y
 # CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
 # CONFIG_FONT_PEARL_8x8 is not set
 # CONFIG_FONT_ACORN_8x8 is not set
 # CONFIG_FONT_MINI_4x6 is not set
 # CONFIG_FONT_SUN8x16 is not set
 # CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
 
 #
 # Logo configuration
@@ -650,12 +767,13 @@ CONFIG_LOGO_SUPERH_CLUT224=y
 #
 # USB support
 #
-# CONFIG_USB is not set
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
 #
@@ -668,16 +786,52 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 #
 # CONFIG_MMC is not set
 
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
 #
 # InfiniBand support
 #
 # CONFIG_INFINIBAND is not set
 
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -687,17 +841,18 @@ CONFIG_JBD=y
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 CONFIG_MINIX_FS=y
 CONFIG_ROMFS_FS=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -717,14 +872,14 @@ CONFIG_DNOTIFY=y
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -748,12 +903,14 @@ CONFIG_RAMFS=y
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -762,6 +919,7 @@ CONFIG_SUNRPC=y
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
 
 #
 # Partition Types
@@ -781,6 +939,7 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 
 #
@@ -796,13 +955,32 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
-CONFIG_DEBUG_KERNEL=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
 CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
 CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_EARLY_PRINTK is not set
 # CONFIG_DEBUG_KERNEL_WITH_GDB_STUB is not set
 CONFIG_SH64_PROC_TLB=y
@@ -823,15 +1001,13 @@ CONFIG_SH64_SR_WATCH=y
 #
 # CONFIG_CRYPTO is not set
 
-#
-# Hardware crypto devices
-#
-
 #
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
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 db475b7833fb86c97b77d70d8c45f9200905dfdf..525d0ec19b7822d597bcd9b6e4efd017295c6249 100644 (file)
 /*
  * This file handles the architecture-dependent parts of process handling..
  */
-
-/* Temporary flags/tests. All to be removed/undefined. BEGIN */
-#define IDLE_TRACE
-#define VM_SHOW_TABLES
-#define VM_TEST_FAULT
-#define VM_TEST_RTLBMISS
-#define VM_TEST_WTLBMISS
-
-#undef VM_SHOW_TABLES
-#undef IDLE_TRACE
-/* Temporary flags/tests. All to be removed/undefined. END */
-
-#define __KERNEL_SYSCALLS__
-#include <stdarg.h>
-
-#include <linux/kernel.h>
-#include <linux/rwsem.h>
 #include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/user.h>
-#include <linux/a.out.h>
-#include <linux/interrupt.h>
-#include <linux/unistd.h>
-#include <linux/delay.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
-
+#include <linux/module.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/processor.h>             /* includes also <asm/registers.h> */
-#include <asm/mmu_context.h>
-#include <asm/elf.h>
-#include <asm/page.h>
-
-#include <linux/irq.h>
 
 struct task_struct *last_task_used_math = NULL;
 
-#ifdef IDLE_TRACE
-#ifdef VM_SHOW_TABLES
-/* For testing */
-static void print_PTE(long base)
-{
-       int i, skip=0;
-       long long x, y, *p = (long long *) base;
-
-       for (i=0; i< 512; i++, p++){
-               if (*p == 0) {
-                       if (!skip) {
-                               skip++;
-                               printk("(0s) ");
-                       }
-               } else {
-                       skip=0;
-                       x = (*p) >> 32;
-                       y = (*p) & 0xffffffff;
-                       printk("%08Lx%08Lx ", x, y);
-                       if (!((i+1)&0x3)) printk("\n");
-               }
-       }
-}
-
-/* For testing */
-static void print_DIR(long base)
-{
-       int i, skip=0;
-       long *p = (long *) base;
-
-       for (i=0; i< 512; i++, p++){
-               if (*p == 0) {
-                       if (!skip) {
-                               skip++;
-                               printk("(0s) ");
-                       }
-               } else {
-                       skip=0;
-                       printk("%08lx ", *p);
-                       if (!((i+1)&0x7)) printk("\n");
-               }
-       }
-}
-
-/* For testing */
-static void print_vmalloc_first_tables(void)
-{
-
-#define PRESENT        0x800   /* Bit 11 */
-
-       /*
-        * Do it really dirty by looking at raw addresses,
-         * raw offsets, no types. If we used pgtable/pgalloc
-        * macros/definitions we could hide potential bugs.
-        *
-        * Note that pointers are 32-bit for CDC.
-        */
-       long pgdt, pmdt, ptet;
-
-       pgdt = (long) &swapper_pg_dir;
-       printk("-->PGD (0x%08lx):\n", pgdt);
-       print_DIR(pgdt);
-       printk("\n");
-
-       /* VMALLOC pool is mapped at 0xc0000000, second (pointer) entry in PGD */
-       pgdt += 4;
-       pmdt = (long) (* (long *) pgdt);
-       if (!(pmdt & PRESENT)) {
-               printk("No PMD\n");
-               return;
-       } else pmdt &= 0xfffff000;
-
-       printk("-->PMD (0x%08lx):\n", pmdt);
-       print_DIR(pmdt);
-       printk("\n");
-
-       /* Get the pmdt displacement for 0xc0000000 */
-       pmdt += 2048;
-
-       /* just look at first two address ranges ... */
-        /* ... 0xc0000000 ... */
-       ptet = (long) (* (long *) pmdt);
-       if (!(ptet & PRESENT)) {
-               printk("No PTE0\n");
-               return;
-       } else ptet &= 0xfffff000;
-
-       printk("-->PTE0 (0x%08lx):\n", ptet);
-       print_PTE(ptet);
-       printk("\n");
-
-        /* ... 0xc0001000 ... */
-       ptet += 4;
-       if (!(ptet & PRESENT)) {
-               printk("No PTE1\n");
-               return;
-       } else ptet &= 0xfffff000;
-       printk("-->PTE1 (0x%08lx):\n", ptet);
-       print_PTE(ptet);
-       printk("\n");
-}
-#else
-#define print_vmalloc_first_tables()
-#endif /* VM_SHOW_TABLES */
-
-static void test_VM(void)
-{
-       void *a, *b, *c;
-
-#ifdef VM_SHOW_TABLES
-       printk("Initial PGD/PMD/PTE\n");
-#endif
-        print_vmalloc_first_tables();
-
-       printk("Allocating 2 bytes\n");
-       a = vmalloc(2);
-        print_vmalloc_first_tables();
-
-       printk("Allocating 4100 bytes\n");
-       b = vmalloc(4100);
-        print_vmalloc_first_tables();
-
-       printk("Allocating 20234 bytes\n");
-       c = vmalloc(20234);
-        print_vmalloc_first_tables();
-
-#ifdef VM_TEST_FAULT
-       /* Here you may want to fault ! */
-
-#ifdef VM_TEST_RTLBMISS
-       printk("Ready to fault upon read.\n");
-       if (* (char *) a) {
-               printk("RTLBMISSed on area a !\n");
-       }
-       printk("RTLBMISSed on area a !\n");
-#endif
-
-#ifdef VM_TEST_WTLBMISS
-       printk("Ready to fault upon write.\n");
-       *((char *) b) = 'L';
-       printk("WTLBMISSed on area b !\n");
-#endif
-
-#endif /* VM_TEST_FAULT */
-
-       printk("Deallocating the 4100 byte chunk\n");
-       vfree(b);
-        print_vmalloc_first_tables();
-
-       printk("Deallocating the 2 byte chunk\n");
-       vfree(a);
-        print_vmalloc_first_tables();
-
-       printk("Deallocating the last chunk\n");
-       vfree(c);
-        print_vmalloc_first_tables();
-}
-
-extern unsigned long volatile jiffies;
-int once = 0;
-unsigned long old_jiffies;
-int pid = -1, pgid = -1;
-
-void idle_trace(void)
-{
-
-       _syscall0(int, getpid)
-       _syscall1(int, getpgid, int, pid)
-
-       if (!once) {
-               /* VM allocation/deallocation simple test */
-               test_VM();
-               pid = getpid();
-
-               printk("Got all through to Idle !!\n");
-               printk("I'm now going to loop forever ...\n");
-               printk("Any ! below is a timer tick.\n");
-               printk("Any . below is a getpgid system call from pid = %d.\n", pid);
-
-
-               old_jiffies = jiffies;
-               once++;
-       }
-
-       if (old_jiffies != jiffies) {
-               old_jiffies = jiffies - old_jiffies;
-               switch (old_jiffies) {
-               case 1:
-                       printk("!");
-                       break;
-               case 2:
-                       printk("!!");
-                       break;
-               case 3:
-                       printk("!!!");
-                       break;
-               case 4:
-                       printk("!!!!");
-                       break;
-               default:
-                       printk("(%d!)", (int) old_jiffies);
-               }
-               old_jiffies = jiffies;
-       }
-       pgid = getpgid(pid);
-       printk(".");
-}
-#else
-#define idle_trace()   do { } while (0)
-#endif /* IDLE_TRACE */
-
 static int hlt_counter = 1;
 
 #define HARD_IDLE_TIMEOUT (HZ / 3)
@@ -323,7 +78,6 @@ void cpu_idle(void)
                        local_irq_disable();
                        while (!need_resched()) {
                                local_irq_enable();
-                               idle_trace();
                                hlt();
                                local_irq_disable();
                        }
@@ -622,6 +376,10 @@ void free_task_struct(struct task_struct *p)
 /*
  * Create a kernel thread
  */
+ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *))
+{
+       do_exit(fn(arg));
+}
 
 /*
  * This is the mechanism for creating a new kernel thread.
@@ -633,19 +391,17 @@ void free_task_struct(struct task_struct *p)
  */
 int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
 {
-       /* A bit less processor dependent than older sh ... */
-       unsigned int reply;
+       struct pt_regs regs;
 
-static __inline__ _syscall2(int,clone,unsigned long,flags,unsigned long,newsp)
-static __inline__ _syscall1(int,exit,int,ret)
+       memset(&regs, 0, sizeof(regs));
+       regs.regs[2] = (unsigned long)arg;
+       regs.regs[3] = (unsigned long)fn;
 
-       reply = clone(flags | CLONE_VM, 0);
-       if (!reply) {
-               /* Child */
-               reply = exit(fn(arg));
-       }
+       regs.pc = (unsigned long)kernel_thread_helper;
+       regs.sr = (1 << 30);
 
-       return reply;
+       return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
+                      &regs, 0, NULL, NULL);
 }
 
 /*
index 58ff7d522d81e0181950954f98608d6594bb3bd3..ad0fa4e003e79c082cfed7c0b5bf00d6a4726a36 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/uaccess.h>
 #include <asm/ipc.h>
 #include <asm/ptrace.h>
+#include <asm/unistd.h>
 
 #define REG_3  3
 
@@ -279,7 +280,25 @@ asmlinkage int sys_uname(struct old_utsname * name)
        if (!name)
                return -EFAULT;
        down_read(&uts_sem);
-       err=copy_to_user(name, &system_utsname, sizeof (*name));
+       err = copy_to_user(name, utsname(), sizeof (*name));
        up_read(&uts_sem);
        return err?-EFAULT:0;
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+       register unsigned long __sc0 __asm__ ("r9") = ((0x13 << 16) | __NR_execve);
+       register unsigned long __sc2 __asm__ ("r2") = (unsigned long) filename;
+       register unsigned long __sc3 __asm__ ("r3") = (unsigned long) argv;
+       register unsigned long __sc4 __asm__ ("r4") = (unsigned long) envp;
+       __asm__ __volatile__ ("trapa    %1 !\t\t\t execve(%2,%3,%4)"
+       : "=r" (__sc0)
+       : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4) );
+       __asm__ __volatile__ ("!dummy   %0 %1 %2 %3"
+       : : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4) : "memory");
+       return __sc0;
+}
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 896863fb208a1a3e61f83f60b6f45860c4076115..a954a0c000002410e518e05f9ba905e8f53ff31a 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/ipc.h>
+#include <asm/unistd.h>
 
 /* #define DEBUG_UNIMP_SYSCALL */
 
@@ -475,16 +476,38 @@ asmlinkage int sys_getdomainname(char __user *name, int len)
 
        down_read(&uts_sem);
        
-       nlen = strlen(system_utsname.domainname) + 1;
+       nlen = strlen(utsname()->domainname) + 1;
        err = -EINVAL;
        if (nlen > len)
                goto out;
 
        err = -EFAULT;
-       if (!copy_to_user(name, system_utsname.domainname, nlen))
+       if (!copy_to_user(name, utsname()->domainname, nlen))
                err = 0;
 
 out:
        up_read(&uts_sem);
        return err;
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+       long __res;
+       register long __g1 __asm__ ("g1") = __NR_execve;
+       register long __o0 __asm__ ("o0") = (long)(filename);
+       register long __o1 __asm__ ("o1") = (long)(argv);
+       register long __o2 __asm__ ("o2") = (long)(envp);
+       asm volatile ("t 0x10\n\t"
+                     "bcc 1f\n\t"
+                     "mov %%o0, %0\n\t"
+                     "sub %%g0, %%o0, %0\n\t"
+                     "1:\n\t"
+                     : "=r" (__res), "=&r" (__o0)
+                     : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1)
+                     : "cc");
+       return __res;
+}
index aa0fb2efb6154241032343e30a748cea59dc5739..6f3ac548ee66dbe908eb157308962e9db489576b 100644 (file)
@@ -325,21 +325,25 @@ struct sunos_dirent_callback {
 #define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1))
 
 static int sunos_filldir(void * __buf, const char * name, int namlen,
-                        loff_t offset, ino_t ino, unsigned int d_type)
+                        loff_t offset, u64 ino, unsigned int d_type)
 {
        struct sunos_dirent __user *dirent;
        struct sunos_dirent_callback * buf = __buf;
+       unsigned long d_ino;
        int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
 
        buf->error = -EINVAL;   /* only used if we fail.. */
        if (reclen > buf->count)
                return -EINVAL;
+       d_ino = ino;
+       if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+               return -EOVERFLOW;
        dirent = buf->previous;
        if (dirent)
                put_user(offset, &dirent->d_off);
        dirent = buf->curr;
        buf->previous = dirent;
-       put_user(ino, &dirent->d_ino);
+       put_user(d_ino, &dirent->d_ino);
        put_user(namlen, &dirent->d_namlen);
        put_user(reclen, &dirent->d_reclen);
        copy_to_user(dirent->d_name, name, namlen);
@@ -406,19 +410,23 @@ struct sunos_direntry_callback {
 };
 
 static int sunos_filldirentry(void * __buf, const char * name, int namlen,
-                             loff_t offset, ino_t ino, unsigned int d_type)
+                             loff_t offset, u64 ino, unsigned int d_type)
 {
        struct sunos_direntry __user *dirent;
        struct sunos_direntry_callback *buf = __buf;
+       unsigned long d_ino;
        int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
 
        buf->error = -EINVAL;   /* only used if we fail.. */
        if (reclen > buf->count)
                return -EINVAL;
+       d_ino = ino;
+       if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+               return -EOVERFLOW;
        dirent = buf->previous;
        dirent = buf->curr;
        buf->previous = dirent;
-       put_user(ino, &dirent->d_ino);
+       put_user(d_ino, &dirent->d_ino);
        put_user(namlen, &dirent->d_namlen);
        put_user(reclen, &dirent->d_reclen);
        copy_to_user(dirent->d_name, name, namlen);
@@ -483,13 +491,18 @@ asmlinkage int sunos_uname(struct sunos_utsname __user *name)
 {
        int ret;
        down_read(&uts_sem);
-       ret = copy_to_user(&name->sname[0], &system_utsname.sysname[0], sizeof(name->sname) - 1);
+       ret = copy_to_user(&name->sname[0], &utsname()->sysname[0],
+                          sizeof(name->sname) - 1);
        if (!ret) {
-               ret |= __copy_to_user(&name->nname[0], &system_utsname.nodename[0], sizeof(name->nname) - 1);
+               ret |= __copy_to_user(&name->nname[0], &utsname()->nodename[0],
+                                     sizeof(name->nname) - 1);
                ret |= __put_user('\0', &name->nname[8]);
-               ret |= __copy_to_user(&name->rel[0], &system_utsname.release[0], sizeof(name->rel) - 1);
-               ret |= __copy_to_user(&name->ver[0], &system_utsname.version[0], sizeof(name->ver) - 1);
-               ret |= __copy_to_user(&name->mach[0], &system_utsname.machine[0], sizeof(name->mach) - 1);
+               ret |= __copy_to_user(&name->rel[0], &utsname()->release[0],
+                                     sizeof(name->rel) - 1);
+               ret |= __copy_to_user(&name->ver[0], &utsname()->version[0],
+                                     sizeof(name->ver) - 1);
+               ret |= __copy_to_user(&name->mach[0], &utsname()->machine[0],
+                                     sizeof(name->mach) - 1);
        }
        up_read(&uts_sem);
        return ret ? -EFAULT : 0;
index 8d8ca716f7a76de2073286e34ac03fc12fa52b3b..b627f8dbcaad5da32b4b5ffe1cad244d820bc898 100644 (file)
@@ -420,7 +420,7 @@ source "arch/sparc64/oprofile/Kconfig"
 
 config KPROBES
        bool "Kprobes (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && MODULES
+       depends on KALLSYMS && EXPERIMENTAL && MODULES
        help
          Kprobes allows you to trap at almost any kernel address and
          execute a callback function.  register_kprobe() establishes
index 0fbdaa5daa8cfbdd6f761481a93d3b1f7b95ff06..f54ab375464b97ff4d1f8a515d597c5ad29121d4 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.18
-# Tue Sep 26 23:09:35 2006
+# Mon Oct  2 14:24:40 2006
 #
 CONFIG_SPARC=y
 CONFIG_SPARC64=y
@@ -35,17 +35,20 @@ CONFIG_LOCALVERSION=""
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_RELAY=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -77,6 +80,7 @@ CONFIG_KMOD=y
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 CONFIG_BLK_DEV_IO_TRACE=y
 
 #
@@ -154,7 +158,7 @@ CONFIG_BINFMT_ELF32=y
 #
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=m
-# CONFIG_SOLARIS_EMUL is not set
+CONFIG_SOLARIS_EMUL=y
 # CONFIG_CMDLINE_BOOL is not set
 
 #
@@ -622,6 +626,7 @@ CONFIG_BNX2=m
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -644,6 +649,7 @@ CONFIG_KEYBOARD_SUNKBD=y
 CONFIG_KEYBOARD_LKKBD=m
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 CONFIG_MOUSE_SERIAL=y
@@ -821,6 +827,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_VT8231 is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
@@ -1092,6 +1099,7 @@ CONFIG_USB_HIDDEV=y
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 
 #
 # USB Imaging devices
@@ -1123,6 +1131,7 @@ CONFIG_USB_HIDDEV=y
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
@@ -1130,9 +1139,9 @@ CONFIG_USB_HIDDEV=y
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
@@ -1256,8 +1265,10 @@ CONFIG_DNOTIFY=y
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
@@ -1374,9 +1385,11 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 # CONFIG_UNWIND_INFO is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_LKDTM is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_DCFLUSH is not set
 # CONFIG_STACK_DEBUG is not set
index e55466c77b61efaf0a8c13172e0dc100bcf3a2a1..0b9c70627ce4e7537d96422d62ff2ac5feb1ba1f 100644 (file)
@@ -4,8 +4,6 @@
  * Copyright (C) 1999 David S. Miller (davem@redhat.com)
  */
 
-#define __KERNEL_SYSCALLS__
-
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -14,6 +12,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/pm.h>
+#include <linux/syscalls.h>
 
 #include <asm/system.h>
 #include <asm/auxio.h>
@@ -98,7 +97,7 @@ again:
 
        /* Ok, down we go... */
        button_pressed = 0;
-       if (execve("/sbin/shutdown", argv, envp) < 0) {
+       if (kernel_execve("/sbin/shutdown", argv, envp) < 0) {
                printk("powerd: shutdown execution failed\n");
                add_wait_queue(&powerd_wait, &wait);
                goto again;
index 708ba9b42cda123a4522326495e2f9118053e166..c45f21b881d5faffd15afed4cd14a81acfca5e3d 100644 (file)
@@ -29,6 +29,7 @@
 #include <asm/psrcompat.h>
 #include <asm/fpumacro.h>
 #include <asm/visasm.h>
+#include <asm/compat_signal.h>
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
index c608c947e6c3dfb125ee6bb75358a7c0049f0ba0..a53d4abb4b49de1193b6a21d1d7e10a96c8eba51 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/utrap.h>
 #include <asm/perfctr.h>
 #include <asm/a.out.h>
+#include <asm/unistd.h>
 
 /* #define DEBUG_UNIMP_SYSCALL */
 
@@ -712,13 +713,13 @@ asmlinkage long sys_getdomainname(char __user *name, int len)
 
        down_read(&uts_sem);
        
-       nlen = strlen(system_utsname.domainname) + 1;
+       nlen = strlen(utsname()->domainname) + 1;
        err = -EINVAL;
        if (nlen > len)
                goto out;
 
        err = -EFAULT;
-       if (!copy_to_user(name, system_utsname.domainname, nlen))
+       if (!copy_to_user(name, utsname()->domainname, nlen))
                err = 0;
 
 out:
@@ -963,3 +964,23 @@ asmlinkage long sys_perfctr(int opcode, unsigned long arg0, unsigned long arg1,
        };
        return err;
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+       long __res;
+       register long __g1 __asm__ ("g1") = __NR_execve;
+       register long __o0 __asm__ ("o0") = (long)(filename);
+       register long __o1 __asm__ ("o1") = (long)(argv);
+       register long __o2 __asm__ ("o2") = (long)(envp);
+       asm volatile ("t 0x6d\n\t"
+                     "sub %%g0, %%o0, %0\n\t"
+                     "movcc %%xcc, %%o0, %0\n\t"
+                     : "=r" (__res), "=&r" (__o0)
+                     : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1)
+                     : "cc");
+       return __res;
+}
index 69444f266e2d5b88526b7019f3a0529de80edd9d..e27cb71bd8e2c09a20bfe7d50b379c80b39abe0a 100644 (file)
@@ -61,6 +61,7 @@
 #include <asm/semaphore.h>
 #include <asm/mmu_context.h>
 #include <asm/a.out.h>
+#include <asm/compat_signal.h>
 
 asmlinkage long sys32_chown16(const char __user * filename, u16 user, u16 group)
 {
@@ -337,12 +338,17 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned
 
 int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
 {
+       compat_ino_t ino;
        int err;
 
        if (stat->size > MAX_NON_LFS || !old_valid_dev(stat->dev) ||
            !old_valid_dev(stat->rdev))
                return -EOVERFLOW;
 
+       ino = stat->ino;
+       if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
+               return -EOVERFLOW;
+
        err  = put_user(old_encode_dev(stat->dev), &statbuf->st_dev);
        err |= put_user(stat->ino, &statbuf->st_ino);
        err |= put_user(stat->mode, &statbuf->st_mode);
index 87ebdf858a3a478c1140185e784f5f03964cfe16..7da72d3b322ae854853ed5f4724219ad8bcb3363 100644 (file)
@@ -43,6 +43,7 @@
 #include <asm/idprom.h> /* for gethostid() */
 #include <asm/unistd.h>
 #include <asm/system.h>
+#include <asm/compat_signal.h>
 
 /* For the nfs mount emulation */
 #include <linux/socket.h>
@@ -280,16 +281,20 @@ static int sunos_filldir(void * __buf, const char * name, int namlen,
        struct sunos_dirent __user *dirent;
        struct sunos_dirent_callback * buf = (struct sunos_dirent_callback *) __buf;
        int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
+       u32 d_ino;
 
        buf->error = -EINVAL;   /* only used if we fail.. */
        if (reclen > buf->count)
                return -EINVAL;
+       d_ino = ino;
+       if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+               return -EOVERFLOW;
        dirent = buf->previous;
        if (dirent)
                put_user(offset, &dirent->d_off);
        dirent = buf->curr;
        buf->previous = dirent;
-       put_user(ino, &dirent->d_ino);
+       put_user(d_ino, &dirent->d_ino);
        put_user(namlen, &dirent->d_namlen);
        put_user(reclen, &dirent->d_reclen);
        if (copy_to_user(dirent->d_name, name, namlen))
@@ -363,14 +368,18 @@ static int sunos_filldirentry(void * __buf, const char * name, int namlen,
        struct sunos_direntry_callback * buf =
                (struct sunos_direntry_callback *) __buf;
        int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
+       u32 d_ino;
 
        buf->error = -EINVAL;   /* only used if we fail.. */
        if (reclen > buf->count)
                return -EINVAL;
+       d_ino = ino;
+       if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+               return -EOVERFLOW;
        dirent = buf->previous;
        dirent = buf->curr;
        buf->previous = dirent;
-       put_user(ino, &dirent->d_ino);
+       put_user(d_ino, &dirent->d_ino);
        put_user(namlen, &dirent->d_namlen);
        put_user(reclen, &dirent->d_reclen);
        if (copy_to_user(dirent->d_name, name, namlen))
@@ -439,16 +448,16 @@ asmlinkage int sunos_uname(struct sunos_utsname __user *name)
        int ret;
 
        down_read(&uts_sem);
-       ret = copy_to_user(&name->sname[0], &system_utsname.sysname[0],
+       ret = copy_to_user(&name->sname[0], &utsname()->sysname[0],
                           sizeof(name->sname) - 1);
-       ret |= copy_to_user(&name->nname[0], &system_utsname.nodename[0],
+       ret |= copy_to_user(&name->nname[0], &utsname()->nodename[0],
                            sizeof(name->nname) - 1);
        ret |= put_user('\0', &name->nname[8]);
-       ret |= copy_to_user(&name->rel[0], &system_utsname.release[0],
+       ret |= copy_to_user(&name->rel[0], &utsname()->release[0],
                            sizeof(name->rel) - 1);
-       ret |= copy_to_user(&name->ver[0], &system_utsname.version[0],
+       ret |= copy_to_user(&name->ver[0], &utsname()->version[0],
                            sizeof(name->ver) - 1);
-       ret |= copy_to_user(&name->mach[0], &system_utsname.machine[0],
+       ret |= copy_to_user(&name->mach[0], &utsname()->machine[0],
                            sizeof(name->mach) - 1);
        up_read(&uts_sem);
        return (ret ? -EFAULT : 0);
index 0f0eb6aa1c401523c9af9fe00057884c00ff3e6f..12a940cc791f3cc0f96c6c39f99d199d514e3048 100644 (file)
@@ -82,12 +82,17 @@ struct sol_stat64 {
 
 static inline int putstat(struct sol_stat __user *ubuf, struct kstat *kbuf)
 {
+       u32 ino;
+
        if (kbuf->size > MAX_NON_LFS ||
            !sysv_valid_dev(kbuf->dev) ||
            !sysv_valid_dev(kbuf->rdev))
                return -EOVERFLOW;
+       ino = kbuf->ino;
+       if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino)
+               return -EOVERFLOW;
        if (put_user (sysv_encode_dev(kbuf->dev), &ubuf->st_dev)        ||
-           __put_user (kbuf->ino, &ubuf->st_ino)               ||
+           __put_user (ino, &ubuf->st_ino)                             ||
            __put_user (kbuf->mode, &ubuf->st_mode)             ||
            __put_user (kbuf->nlink, &ubuf->st_nlink)   ||
            __put_user (kbuf->uid, &ubuf->st_uid)               ||
index 9c581328e76a191e3b4aa4903840276db2c3aab2..9ed997982f8dbe245e2f3a15fab1257ee9c10c56 100644 (file)
@@ -249,7 +249,7 @@ asmlinkage int solaris_utssys(u32 buf, u32 flags, int which, u32 buf2)
                /* Let's cheat */
                err  = set_utsfield(v->sysname, "SunOS", 1, 0);
                down_read(&uts_sem);
-               err |= set_utsfield(v->nodename, system_utsname.nodename,
+               err |= set_utsfield(v->nodename, utsname()->nodename,
                                    1, 1);
                up_read(&uts_sem);
                err |= set_utsfield(v->release, "2.6", 0, 0);
@@ -273,7 +273,7 @@ asmlinkage int solaris_utsname(u32 buf)
        /* Why should we not lie a bit? */
        down_read(&uts_sem);
        err  = set_utsfield(v->sysname, "SunOS", 0, 0);
-       err |= set_utsfield(v->nodename, system_utsname.nodename, 1, 1);
+       err |= set_utsfield(v->nodename, utsname()->nodename, 1, 1);
        err |= set_utsfield(v->release, "5.6", 0, 0);
        err |= set_utsfield(v->version, "Generic", 0, 0);
        err |= set_utsfield(v->machine, machine(), 0, 0);
@@ -305,7 +305,7 @@ asmlinkage int solaris_sysinfo(int cmd, u32 buf, s32 count)
        case SI_HOSTNAME:
                r = buffer + 256;
                down_read(&uts_sem);
-               for (p = system_utsname.nodename, q = buffer; 
+               for (p = utsname()->nodename, q = buffer;
                     q < r && *p && *p != '.'; *q++ = *p++);
                up_read(&uts_sem);
                *q = 0;
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 563ce7690a1eb66ccf38376da5c68c591666a7ea..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;
  */
 
@@ -642,9 +642,9 @@ int line_remove(struct line *lines, unsigned int num, int n)
 }
 
 struct tty_driver *line_register_devfs(struct lines *set,
-                        struct line_driver *line_driver,
-                        struct tty_operations *ops, struct line *lines,
-                        int nlines)
+                                      struct line_driver *line_driver,
+                                      const struct tty_operations *ops,
+                                      struct line *lines, int nlines)
 {
        int i;
        struct tty_driver *driver = alloc_tty_driver(nlines);
index 773a134e7fdb806fd6b63c80ceb3576ede57a370..a67dcbd78de4765c7f7f54d7f907cfd01449c2c3 100644 (file)
@@ -106,9 +106,9 @@ void mconsole_version(struct mc_request *req)
 {
        char version[256];
 
-       sprintf(version, "%s %s %s %s %s", system_utsname.sysname,
-               system_utsname.nodename, system_utsname.release,
-               system_utsname.version, system_utsname.machine);
+       sprintf(version, "%s %s %s %s %s", utsname()->sysname,
+               utsname()->nodename, utsname()->release,
+               utsname()->version, utsname()->machine);
        mconsole_reply(req, version, 0, 0);
 }
 
index 642c9a0320f9a111af988a8dead98a08ef107efb..7be24811bb3094b127667941f06c7297c085f2e9 100644 (file)
@@ -91,10 +91,9 @@ extern int line_setup_irq(int fd, int input, int output, struct line *line,
                          void *data);
 extern void line_close_chan(struct line *line);
 extern struct tty_driver * line_register_devfs(struct lines *set,
-                               struct line_driver *line_driver,
-                               struct tty_operations *driver,
-                               struct line *lines,
-                               int nlines);
+                                              struct line_driver *line_driver,
+                                              const struct tty_operations *driver,
+                                              struct line *lines, int nlines);
 extern void lines_init(struct line *lines, int nlines, struct chan_opts *opts);
 extern void close_lines(struct line *lines, int nlines);
 
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 48cf88dd02d4daaf94c0aca862065eb9abeb8388..f5ed8624648b88f0b0022a5994f202361fea19fb 100644 (file)
@@ -110,7 +110,7 @@ long sys_uname(struct old_utsname __user * name)
        if (!name)
                return -EFAULT;
        down_read(&uts_sem);
-       err = copy_to_user(name, &system_utsname, sizeof (*name));
+       err = copy_to_user(name, utsname(), sizeof (*name));
        up_read(&uts_sem);
        return err?-EFAULT:0;
 }
@@ -126,21 +126,21 @@ long sys_olduname(struct oldold_utsname __user * name)
 
        down_read(&uts_sem);
 
-       error = __copy_to_user(&name->sysname,&system_utsname.sysname,
+       error = __copy_to_user(&name->sysname, &utsname()->sysname,
                               __OLD_UTS_LEN);
-       error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
-       error |= __copy_to_user(&name->nodename,&system_utsname.nodename,
+       error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
+       error |= __copy_to_user(&name->nodename, &utsname()->nodename,
                                __OLD_UTS_LEN);
-       error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
-       error |= __copy_to_user(&name->release,&system_utsname.release,
+       error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
+       error |= __copy_to_user(&name->release, &utsname()->release,
                                __OLD_UTS_LEN);
-       error |= __put_user(0,name->release+__OLD_UTS_LEN);
-       error |= __copy_to_user(&name->version,&system_utsname.version,
+       error |= __put_user(0, name->release + __OLD_UTS_LEN);
+       error |= __copy_to_user(&name->version, &utsname()->version,
                                __OLD_UTS_LEN);
-       error |= __put_user(0,name->version+__OLD_UTS_LEN);
-       error |= __copy_to_user(&name->machine,&system_utsname.machine,
+       error |= __put_user(0, name->version + __OLD_UTS_LEN);
+       error |= __copy_to_user(&name->machine, &utsname()->machine,
                                __OLD_UTS_LEN);
-       error |= __put_user(0,name->machine+__OLD_UTS_LEN);
+       error |= __put_user(0, name->machine + __OLD_UTS_LEN);
 
        up_read(&uts_sem);
 
@@ -164,3 +164,16 @@ int next_syscall_index(int limit)
        spin_unlock(&syscall_lock);
        return(ret);
 }
+
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+       mm_segment_t fs;
+       int ret;
+
+       fs = get_fs();
+       set_fs(KERNEL_DS);
+       ret = um_execve(filename, argv, envp);
+       set_fs(fs);
+
+       return ret;
+}
index 55005710dcbbc8254fc3bbea46f3f3b6ad065ad1..97d88e7902f7dbb71f19b62facbf652fe854575f 100644 (file)
@@ -167,7 +167,7 @@ static char *usage_string =
 
 static int __init uml_version_setup(char *line, int *add)
 {
-       printf("%s\n", system_utsname.release);
+       printf("%s\n", init_utsname()->release);
        exit(0);
 
        return 0;
@@ -278,7 +278,7 @@ static int __init Usage(char *line, int *add)
 {
        const char **p;
 
-       printf(usage_string, system_utsname.release);
+       printf(usage_string, init_utsname()->release);
        p = &__uml_help_start;
        while (p < &__uml_help_end) {
                printf("%s", *p);
@@ -403,7 +403,7 @@ int linux_main(int argc, char **argv)
        /* Reserve up to 4M after the current brk */
        uml_reserved = ROUND_4M(brk_start) + (1 << 22);
 
-       setup_machinename(system_utsname.machine);
+       setup_machinename(init_utsname()->machine);
 
 #ifdef CONFIG_CMDLINE_ON_HOST
        argv1_begin = argv[1];
index ff203625a4bd9afb44ddc1c918a79df2dbc3d608..51f0893640a6ff39f7c42519506d7dae9ec6c3de 100644 (file)
@@ -11,6 +11,7 @@
 #include <sys/mman.h>
 #include <sys/wait.h>
 #include <sys/mman.h>
+#include <sys/syscall.h>
 #include "ptrace_user.h"
 #include "os.h"
 #include "user.h"
@@ -140,11 +141,9 @@ void os_usr1_process(int pid)
  * syscalls, and also breaks with clone(), which does not unshare the TLS.
  */
 
-inline _syscall0(pid_t, getpid)
-
 int os_getpid(void)
 {
-       return(getpid());
+       return(syscall(__NR_getpid));
 }
 
 int os_getpgrp(void)
index 120abbe4e3ce2916d7d20eb7680dcdfd2a8c0baa..6e945ab4584324b6b6df71a7c32688c7cde95538 100644 (file)
@@ -1,10 +1,9 @@
 #include <errno.h>
 #include <linux/unistd.h>
+#include <sys/syscall.h>
 #include "sysdep/tls.h"
 #include "user_util.h"
 
-static _syscall1(int, get_thread_area, user_desc_t *, u_info);
-
 /* Checks whether host supports TLS, and sets *tls_min according to the value
  * valid on the host.
  * i386 host have it == 6; x86_64 host have it == 12, for i386 emulation. */
@@ -17,7 +16,7 @@ void check_host_supports_tls(int *supports_tls, int *tls_min) {
                user_desc_t info;
                info.entry_number = val[i];
 
-               if (get_thread_area(&info) == 0) {
+               if (syscall(__NR_get_thread_area, &info) == 0) {
                        *tls_min = val[i];
                        *supports_tls = 1;
                        return;
index 9cb09a45546b8828bd105729897ad431f6c509c1..a2de2580b8af4716593832ef880d1c930042c21b 100644 (file)
@@ -1,5 +1,6 @@
 #include <errno.h>
 #include <sys/ptrace.h>
+#include <sys/syscall.h>
 #include <asm/ldt.h>
 #include "sysdep/tls.h"
 #include "uml-config.h"
@@ -48,14 +49,11 @@ int os_get_thread_area(user_desc_t *info, int pid)
 #ifdef UML_CONFIG_MODE_TT
 #include "linux/unistd.h"
 
-static _syscall1(int, get_thread_area, user_desc_t *, u_info);
-static _syscall1(int, set_thread_area, user_desc_t *, u_info);
-
 int do_set_thread_area_tt(user_desc_t *info)
 {
        int ret;
 
-       ret = set_thread_area(info);
+       ret = syscall(__NR_set_thread_area,info);
        if (ret < 0) {
                ret = -errno;
        }
@@ -66,7 +64,7 @@ int do_get_thread_area_tt(user_desc_t *info)
 {
        int ret;
 
-       ret = get_thread_area(info);
+       ret = syscall(__NR_get_thread_area,info);
        if (ret < 0) {
                ret = -errno;
        }
index 1b0ad0e4adcd26d29f0b605266dfea0cfb1f19d2..8e55cd5d3d07230bb5d98d5a5113fd6b707cec8a 100644 (file)
@@ -5,20 +5,17 @@
 
 #include <linux/mman.h>
 #include <asm/unistd.h>
+#include <sys/syscall.h>
 
-static int errno;
-
-static inline _syscall2(int,munmap,void *,start,size_t,len)
-static inline _syscall6(void *,mmap2,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset)
 int switcheroo(int fd, int prot, void *from, void *to, int size)
 {
-       if(munmap(to, size) < 0){
+       if (syscall(__NR_munmap, to, size) < 0){
                return(-1);
        }
-       if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){
+       if (syscall(__NR_mmap2, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){
                return(-1);
        }
-       if(munmap(from, size) < 0){
+       if (syscall(__NR_munmap, from, size) < 0){
                return(-1);
        }
        return(0);
index 6fce9f45dfdc0257aafafaf543afffcfc42127e3..73ce4463f70c6f96b2cd94f000b69df5a0da95ff 100644 (file)
@@ -21,7 +21,7 @@ asmlinkage long sys_uname64(struct new_utsname __user * name)
 {
        int err;
        down_read(&uts_sem);
-       err = copy_to_user(name, &system_utsname, sizeof (*name));
+       err = copy_to_user(name, utsname(), sizeof (*name));
        up_read(&uts_sem);
        if (personality(current->personality) == PER_LINUX32)
                err |= copy_to_user(&name->machine, "i686", 5);
index d0a25af19a5bd216dc2995807fb0ed410238b44e..ce3e07fcf283747bdb72216bcf2f7968d2abe0af 100644 (file)
@@ -16,7 +16,7 @@ void __show_regs(struct pt_regs * regs)
        printk("\n");
        print_modules();
        printk("Pid: %d, comm: %.20s %s %s\n",
-              current->pid, current->comm, print_tainted(), system_utsname.release);
+              current->pid, current->comm, print_tainted(), init_utsname()->release);
        printk("RIP: %04lx:[<%016lx>] ", PT_REGS_CS(regs) & 0xffff,
               PT_REGS_RIP(regs));
        printk("\nRSP: %016lx  EFLAGS: %08lx\n", PT_REGS_RSP(regs),
index f4a4bffd8a18bc5fb4f6aadce49fb466453d11bd..57c9286a701bcdc71df35740973674b8c603684e 100644 (file)
@@ -5,20 +5,17 @@
 
 #include <linux/mman.h>
 #include <asm/unistd.h>
+#include <sys/syscall.h>
 
-static int errno;
-
-static inline _syscall2(int,munmap,void *,start,size_t,len)
-static inline _syscall6(void *,mmap,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset)
 int switcheroo(int fd, int prot, void *from, void *to, int size)
 {
-       if(munmap(to, size) < 0){
+       if (syscall(__NR_munmap, to, size) < 0){
                return(-1);
        }
-       if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){
+       if (syscall(__NR_mmap, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){
                return(-1);
        }
-       if(munmap(from, size) < 0){
+       if (syscall(__NR_munmap, from, size) < 0){
                return(-1);
        }
        return(0);
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 815f8a43926fab1f51c5bde3f7ecef16cd53d700..92f514fdcc79fa608e98093e1d003d506ef0eaf1 100644 (file)
@@ -104,7 +104,7 @@ int memcons_tty_chars_in_buffer (struct tty_struct *tty)
        return 0;
 }
 
-static struct tty_operations ops = {
+static const struct tty_operations ops = {
        .open = memcons_tty_open,
        .write = memcons_tty_write,
        .write_room = memcons_tty_write_room,
index 3975aa02cef83df866a58085bb384715c87a3423..9973596ae3044e7dffc937bf8fc074f06ae451c5 100644 (file)
@@ -77,7 +77,7 @@ int simcons_tty_chars_in_buffer (struct tty_struct *tty)
        return 0;
 }
 
-static struct tty_operations ops = {
+static const struct tty_operations ops = {
        .open = simcons_tty_open,
        .write = simcons_tty_write,
        .write_room = simcons_tty_write_room,
index 2ec0700fc46bc75cc0ab9c312c0be75cdba674b9..d2b1fb19d24313d22896da6d72c710113ddaf9ef 100644 (file)
@@ -33,6 +33,7 @@
 #include <asm/uaccess.h>
 #include <asm/ipc.h>
 #include <asm/semaphore.h>
+#include <asm/unistd.h>
 
 /*
  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
@@ -194,3 +195,22 @@ unsigned long sys_mmap (unsigned long addr, size_t len,
 out:
        return err;
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+       register char *__a __asm__ ("r6") = filename;
+       register void *__b __asm__ ("r7") = argv;
+       register void *__c __asm__ ("r8") = envp;
+       register unsigned long __syscall __asm__ ("r12") = __NR_execve;
+       register unsigned long __ret __asm__ ("r10");
+       __asm__ __volatile__ ("trap 0"
+                       : "=r" (__ret), "=r" (__syscall)
+                       : "1" (__syscall), "r" (__a), "r" (__b), "r" (__c)
+                       : "r1", "r5", "r11", "r13", "r14",
+                         "r15", "r16", "r17", "r18", "r19");
+       return __ret;
+}
index b87a19f0d584910f2c0438308d007c5515968b3f..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.   
 
@@ -690,7 +690,7 @@ source "arch/x86_64/oprofile/Kconfig"
 
 config KPROBES
        bool "Kprobes (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && MODULES
+       depends on KALLSYMS && EXPERIMENTAL && MODULES
        help
          Kprobes allows you to trap at almost any kernel address and
          execute a callback function.  register_kprobe() establishes
index f280d3665f4bed8fa07513078f39113369814354..c9bac3af29d6a746be28d38a241667e78593df3f 100644 (file)
@@ -76,6 +76,8 @@
 
 int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf)
 {
+       compat_ino_t ino;
+
        typeof(ubuf->st_uid) uid = 0;
        typeof(ubuf->st_gid) gid = 0;
        SET_UID(uid, kbuf->uid);
@@ -84,9 +86,12 @@ int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf)
                return -EOVERFLOW;
        if (kbuf->size >= 0x7fffffff)
                return -EOVERFLOW;
+       ino = kbuf->ino;
+       if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino)
+               return -EOVERFLOW;
        if (!access_ok(VERIFY_WRITE, ubuf, sizeof(struct compat_stat)) ||
            __put_user (old_encode_dev(kbuf->dev), &ubuf->st_dev) ||
-           __put_user (kbuf->ino, &ubuf->st_ino) ||
+           __put_user (ino, &ubuf->st_ino) ||
            __put_user (kbuf->mode, &ubuf->st_mode) ||
            __put_user (kbuf->nlink, &ubuf->st_nlink) ||
            __put_user (uid, &ubuf->st_uid) ||
@@ -784,36 +789,36 @@ asmlinkage long sys32_olduname(struct oldold_utsname __user * name)
 
        if (!name)
                return -EFAULT;
-       if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
+       if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname)))
                return -EFAULT;
   
        down_read(&uts_sem);
-       
-       err = __copy_to_user(&name->sysname,&system_utsname.sysname,
+
+       err = __copy_to_user(&name->sysname,&utsname()->sysname,
                                __OLD_UTS_LEN);
        err |= __put_user(0,name->sysname+__OLD_UTS_LEN);
-       err |= __copy_to_user(&name->nodename,&system_utsname.nodename,
+       err |= __copy_to_user(&name->nodename,&utsname()->nodename,
                                __OLD_UTS_LEN);
        err |= __put_user(0,name->nodename+__OLD_UTS_LEN);
-       err |= __copy_to_user(&name->release,&system_utsname.release,
+       err |= __copy_to_user(&name->release,&utsname()->release,
                                __OLD_UTS_LEN);
        err |= __put_user(0,name->release+__OLD_UTS_LEN);
-       err |= __copy_to_user(&name->version,&system_utsname.version,
+       err |= __copy_to_user(&name->version,&utsname()->version,
                                __OLD_UTS_LEN);
        err |= __put_user(0,name->version+__OLD_UTS_LEN);
-        { 
-                char *arch = "x86_64";
-                if (personality(current->personality) == PER_LINUX32)
-                        arch = "i686";
+       {
+               char *arch = "x86_64";
+               if (personality(current->personality) == PER_LINUX32)
+                       arch = "i686";
                 
-                err |= __copy_to_user(&name->machine,arch,strlen(arch)+1);
-        }
-       
-        up_read(&uts_sem);
-        
-        err = err ? -EFAULT : 0;
-        
-        return err;
+               err |= __copy_to_user(&name->machine, arch, strlen(arch)+1);
+       }
+
+       up_read(&uts_sem);
+
+       err = err ? -EFAULT : 0;
+
+       return err;
 }
 
 long sys32_uname(struct old_utsname __user * name)
@@ -822,7 +827,7 @@ long sys32_uname(struct old_utsname __user * name)
        if (!name)
                return -EFAULT;
        down_read(&uts_sem);
-       err=copy_to_user(name, &system_utsname, sizeof (*name));
+       err = copy_to_user(name, utsname(), sizeof (*name));
        up_read(&uts_sem);
        if (personality(current->personality) == PER_LINUX32) 
                err |= copy_to_user(&name->machine, "i686", 5);
index 135ff25e6b449ad613671756ff3ba0c0b37ae018..6472e321cad7d0d6d682cf8e846a7f48ea761086 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/kernel_stat.h>
 #include <linux/sysdev.h>
 #include <linux/module.h>
-#include <linux/ioport.h>
 
 #include <asm/atomic.h>
 #include <asm/smp.h>
@@ -46,11 +45,6 @@ int apic_calibrate_pmtmr __initdata;
 
 int disable_apic_timer __initdata;
 
-static struct resource lapic_resource = {
-       .name = "Local APIC",
-       .flags = IORESOURCE_MEM | IORESOURCE_BUSY,
-};
-
 /*
  * cpu_mask that denotes the CPUs that needs timer interrupt coming in as
  * IPIs in place of local APIC timers
@@ -591,40 +585,6 @@ static int __init detect_init_APIC (void)
        return 0;
 }
 
-#ifdef CONFIG_X86_IO_APIC
-static struct resource * __init ioapic_setup_resources(void)
-{
-#define IOAPIC_RESOURCE_NAME_SIZE 11
-       unsigned long n;
-       struct resource *res;
-       char *mem;
-       int i;
-
-       if (nr_ioapics <= 0)
-               return NULL;
-
-       n = IOAPIC_RESOURCE_NAME_SIZE + sizeof(struct resource);
-       n *= nr_ioapics;
-
-       res = alloc_bootmem(n);
-
-       if (!res)
-               return NULL;
-
-       memset(res, 0, n);
-       mem = (void *)&res[nr_ioapics];
-
-       for (i = 0; i < nr_ioapics; i++) {
-               res[i].name = mem;
-               res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-               snprintf(mem, IOAPIC_RESOURCE_NAME_SIZE, "IOAPIC %u", i);
-               mem += IOAPIC_RESOURCE_NAME_SIZE;
-       }
-
-       return res;
-}
-#endif
-
 void __init init_apic_mappings(void)
 {
        unsigned long apic_phys;
@@ -644,11 +604,6 @@ void __init init_apic_mappings(void)
        apic_mapped = 1;
        apic_printk(APIC_VERBOSE,"mapped APIC to %16lx (%16lx)\n", APIC_BASE, apic_phys);
 
-       /* Put local APIC into the resource map. */
-       lapic_resource.start = apic_phys;
-       lapic_resource.end = lapic_resource.start + PAGE_SIZE - 1;
-       insert_resource(&iomem_resource, &lapic_resource);
-
        /*
         * Fetch the APIC ID of the BSP in case we have a
         * default configuration (or the MP table is broken).
@@ -658,9 +613,7 @@ void __init init_apic_mappings(void)
        {
                unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0;
                int i;
-               struct resource *ioapic_res;
 
-               ioapic_res = ioapic_setup_resources();
                for (i = 0; i < nr_ioapics; i++) {
                        if (smp_found_config) {
                                ioapic_phys = mp_ioapics[i].mpc_apicaddr;
@@ -672,13 +625,6 @@ void __init init_apic_mappings(void)
                        apic_printk(APIC_VERBOSE,"mapped IOAPIC to %016lx (%016lx)\n",
                                        __fix_to_virt(idx), ioapic_phys);
                        idx++;
-
-                       if (ioapic_res) {
-                               ioapic_res->start = ioapic_phys;
-                               ioapic_res->end = ioapic_phys + (4 * 1024) - 1;
-                               insert_resource(&iomem_resource, ioapic_res);
-                               ioapic_res++;
-                       }
                }
        }
 }
index 2802524104f32da51e268cdc6b540efccccb93e1..b8285cf1a9c3b2780bdd53c499047856d378195d 100644 (file)
@@ -1023,7 +1023,7 @@ ENDPROC(child_rip)
  * do_sys_execve asm fallback arguments:
  *     rdi: name, rsi: argv, rdx: envp, fake frame on the stack
  */
-ENTRY(execve)
+ENTRY(kernel_execve)
        CFI_STARTPROC
        FAKE_STACK_FRAME $0
        SAVE_ALL        
@@ -1036,7 +1036,7 @@ ENTRY(execve)
        UNFAKE_STACK_FRAME
        ret
        CFI_ENDPROC
-ENDPROC(execve)
+ENDPROC(kernel_execve)
 
 KPROBE_ENTRY(page_fault)
        errorentry do_page_fault
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 ffc73ac72485f666befc9e7b13c730930fd6681b..ac241567e682eb45c4a7918b805082cddd52f5cb 100644 (file)
@@ -270,20 +270,19 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
                                      struct pt_regs *regs)
 {
        unsigned long *sara = (unsigned long *)regs->rsp;
-        struct kretprobe_instance *ri;
+       struct kretprobe_instance *ri;
 
-        if ((ri = get_free_rp_inst(rp)) != NULL) {
-                ri->rp = rp;
-                ri->task = current;
+       if ((ri = get_free_rp_inst(rp)) != NULL) {
+               ri->rp = rp;
+               ri->task = current;
                ri->ret_addr = (kprobe_opcode_t *) *sara;
 
                /* Replace the return addr with trampoline addr */
                *sara = (unsigned long) &kretprobe_trampoline;
-
-                add_rp_inst(ri);
-        } else {
-                rp->nmissed++;
-        }
+               add_rp_inst(ri);
+       } else {
+               rp->nmissed++;
+       }
 }
 
 int __kprobes kprobe_handler(struct pt_regs *regs)
@@ -405,14 +404,15 @@ no_kprobe:
  */
 int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
 {
-        struct kretprobe_instance *ri = NULL;
-        struct hlist_head *head;
-        struct hlist_node *node, *tmp;
+       struct kretprobe_instance *ri = NULL;
+       struct hlist_head *head, empty_rp;
+       struct hlist_node *node, *tmp;
        unsigned long flags, orig_ret_address = 0;
        unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
 
+       INIT_HLIST_HEAD(&empty_rp);
        spin_lock_irqsave(&kretprobe_lock, flags);
-        head = kretprobe_inst_table_head(current);
+       head = kretprobe_inst_table_head(current);
 
        /*
         * It is possible to have multiple instances associated with a given
@@ -423,20 +423,20 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
         * We can handle this because:
         *     - instances are always inserted at the head of the list
         *     - when multiple return probes are registered for the same
-         *       function, the first instance's ret_addr will point to the
+        *       function, the first instance's ret_addr will point to the
         *       real return address, and all the rest will point to
         *       kretprobe_trampoline
         */
        hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
-                if (ri->task != current)
+               if (ri->task != current)
                        /* another task is sharing our hash bucket */
-                        continue;
+                       continue;
 
                if (ri->rp && ri->rp->handler)
                        ri->rp->handler(ri, regs);
 
                orig_ret_address = (unsigned long)ri->ret_addr;
-               recycle_rp_inst(ri);
+               recycle_rp_inst(ri, &empty_rp);
 
                if (orig_ret_address != trampoline_address)
                        /*
@@ -454,12 +454,16 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
        spin_unlock_irqrestore(&kretprobe_lock, flags);
        preempt_enable_no_resched();
 
-        /*
-         * By returning a non-zero value, we are telling
-         * kprobe_handler() that we don't want the post_handler
+       hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
+               hlist_del(&ri->hlist);
+               kfree(ri);
+       }
+       /*
+        * By returning a non-zero value, we are telling
+        * kprobe_handler() that we don't want the post_handler
         * to run (and have re-enabled preemption)
-         */
-        return 1;
+        */
+       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 458006ae19f3837c240477611cdcb6c1e3df503f..de10cb8a2c97b8cde91e730bcb1486442fc4f82e 100644 (file)
@@ -294,9 +294,9 @@ void __show_regs(struct pt_regs * regs)
        print_modules();
        printk("Pid: %d, comm: %.20s %s %s %.*s\n",
                current->pid, current->comm, print_tainted(),
-               system_utsname.release,
-               (int)strcspn(system_utsname.version, " "),
-               system_utsname.version);
+               init_utsname()->release,
+               (int)strcspn(init_utsname()->version, " "),
+               init_utsname()->version);
        printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip);
        printk_address(regs->rip); 
        printk("RSP: %04lx:%016lx  EFLAGS: %08lx\n", regs->ss, regs->rsp,
index 6449ea8fe756475b7316bdaa51ddd16e3c2c6dd9..76bf7c241fe410fdd676b17c6bce41143293a883 100644 (file)
@@ -148,7 +148,7 @@ asmlinkage long sys_uname(struct new_utsname __user * name)
 {
        int err;
        down_read(&uts_sem);
-       err = copy_to_user(name, &system_utsname, sizeof (*name));
+       err = copy_to_user(name, utsname(), sizeof (*name));
        up_read(&uts_sem);
        if (personality(current->personality) == PER_LINUX32) 
                err |= copy_to_user(&name->machine, "i686", 5);                 
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 4688ba2db84d5c46c8ae060bec50fe891454bf4b..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
@@ -128,7 +128,7 @@ out:
 
 int sys_uname(struct old_utsname * name)
 {
-       if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
+       if (name && !copy_to_user(name, utsname(), sizeof (*name)))
                return 0;
        return -EFAULT;
 }
@@ -266,3 +266,23 @@ void system_call (struct pt_regs *regs)
        regs->areg[2] = res;
        do_syscall_trace();
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+       long __res;
+       asm volatile (
+               "  mov   a5, %2 \n"
+               "  mov   a4, %4 \n"
+               "  mov   a3, %3 \n"
+               "  movi  a2, %1 \n"
+               "  syscall      \n"
+               "  mov   %0, a2 \n"
+               : "=a" (__res)
+               : "i" (__NR_execve), "a" (filename), "a" (argv), "a" (envp)
+               : "a2", "a3", "a4", "a5");
+       return __res;
+}
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 22d3c571a7bc70c8927b19cd17ec19990185a3e3..5c947cae75207d91825ead1b34cf59fdc516bcf7 100644 (file)
@@ -191,7 +191,7 @@ static int rs_read_proc(char *page, char **start, off_t off, int count,
 }
 
 
-static struct tty_operations serial_ops = {
+static const struct tty_operations serial_ops = {
        .open = rs_open,
        .close = rs_close,
        .write = rs_write,
index 309760b7e37f0c9a7d08ddcf047196dc1eb70875..58aab630dfc1a55eaf06975d5a48600b5f14e49e 100644 (file)
@@ -199,8 +199,8 @@ static int blkdev_locked_ioctl(struct file *file, struct block_device *bdev,
        return -ENOIOCTLCMD;
 }
 
-static int blkdev_driver_ioctl(struct inode *inode, struct file *file,
-               struct gendisk *disk, unsigned cmd, unsigned long arg)
+int blkdev_driver_ioctl(struct inode *inode, struct file *file,
+                       struct gendisk *disk, unsigned cmd, unsigned long arg)
 {
        int ret;
        if (disk->fops->unlocked_ioctl)
@@ -215,6 +215,7 @@ static int blkdev_driver_ioctl(struct inode *inode, struct file *file,
 
        return -ENOTTY;
 }
+EXPORT_SYMBOL_GPL(blkdev_driver_ioctl);
 
 int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
                        unsigned long arg)
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 cf656ecbe5073359b3c02b5faaeee9313f476740..6d3e4c0f15febf1c6a9afd125cedca6b0d5a932c 100644 (file)
@@ -429,7 +429,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 
        /* PCI clocking determines the ATA timing values to use */
        /* info_hpt366 is safe against re-entry so we can scribble on it */
-       switch(reg1 & 0x700) {
+       switch((reg1 & 0x700) >> 8) {
                case 5:
                        info_hpt366.private_data = &hpt366_40;
                        break;
@@ -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 6cc93de0b71d120bcae769c97d9a477d1612caa6..ac2c10822be07c41e5f3995dee1f260099ce3bc2 100644 (file)
@@ -113,15 +113,13 @@ static int __init adummy_init(void)
 
        printk(KERN_ERR "adummy: version %s\n", DRV_VERSION);
 
-       adummy_dev = (struct adummy_dev *) kmalloc(sizeof(struct adummy_dev),
+       adummy_dev = kzalloc(sizeof(struct adummy_dev),
                                                   GFP_KERNEL);
        if (!adummy_dev) {
-               printk(KERN_ERR DEV_LABEL ": kmalloc() failed\n");
+               printk(KERN_ERR DEV_LABEL ": kzalloc() failed\n");
                err = -ENOMEM;
                goto out;
        }
-       memset(adummy_dev, 0, sizeof(struct adummy_dev));
-
        atm_dev = atm_dev_register(DEV_LABEL, &adummy_ops, -1, NULL);
        if (!atm_dev) {
                printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n");
index 4521a249dd5632b0555c621c43ab4f974be0a627..da599e6e9d34c2fd47aa02bac6c615704f2a9244 100644 (file)
@@ -915,8 +915,8 @@ static irqreturn_t interrupt_handler(int irq, void *dev_id,
 
 /********** make rate (not quite as much fun as Horizon) **********/
 
-static unsigned int make_rate (unsigned int rate, rounding r,
-                              u16 * bits, unsigned int * actual) {
+static int make_rate (unsigned int rate, rounding r,
+                     u16 * bits, unsigned int * actual) {
   unsigned char exp = -1; // hush gcc
   unsigned int man = -1;  // hush gcc
   
index 38fc054bd6715246f261f5a2e88e432026ef92eb..5f25e5efefcd72838f46ab9a1b1dcd62aff2d21b 100644 (file)
@@ -1784,7 +1784,7 @@ static int __devinit fs_init (struct fs_dev *dev)
                write_fs (dev, RAM, (1 << (28 - FS155_VPI_BITS - FS155_VCI_BITS)) - 1);
                dev->nchannels = FS155_NR_CHANNELS;
        }
-       dev->atm_vccs = kmalloc (dev->nchannels * sizeof (struct atm_vcc *), 
+       dev->atm_vccs = kcalloc (dev->nchannels, sizeof (struct atm_vcc *),
                                 GFP_KERNEL);
        fs_dprintk (FS_DEBUG_ALLOC, "Alloc atmvccs: %p(%Zd)\n",
                    dev->atm_vccs, dev->nchannels * sizeof (struct atm_vcc *));
@@ -1794,9 +1794,8 @@ static int __devinit fs_init (struct fs_dev *dev)
                /* XXX Clean up..... */
                return 1;
        }
-       memset (dev->atm_vccs, 0, dev->nchannels * sizeof (struct atm_vcc *));
 
-       dev->tx_inuse = kmalloc (dev->nchannels / 8 /* bits/byte */ , GFP_KERNEL);
+       dev->tx_inuse = kzalloc (dev->nchannels / 8 /* bits/byte */ , GFP_KERNEL);
        fs_dprintk (FS_DEBUG_ALLOC, "Alloc tx_inuse: %p(%d)\n", 
                    dev->atm_vccs, dev->nchannels / 8);
 
@@ -1805,8 +1804,6 @@ static int __devinit fs_init (struct fs_dev *dev)
                /* XXX Clean up..... */
                return 1;
        }
-       memset (dev->tx_inuse, 0, dev->nchannels / 8);
-
        /* -- RAS1 : FS155 and 50 differ. Default (0) should be OK for both */
        /* -- RAS2 : FS50 only: Default is OK. */
 
@@ -1893,14 +1890,11 @@ static int __devinit firestream_init_one (struct pci_dev *pci_dev,
        if (pci_enable_device(pci_dev)) 
                goto err_out;
 
-       fs_dev = kmalloc (sizeof (struct fs_dev), GFP_KERNEL);
+       fs_dev = kzalloc (sizeof (struct fs_dev), GFP_KERNEL);
        fs_dprintk (FS_DEBUG_ALLOC, "Alloc fs-dev: %p(%Zd)\n",
                    fs_dev, sizeof (struct fs_dev));
        if (!fs_dev)
                goto err_out;
-
-       memset (fs_dev, 0, sizeof (struct fs_dev));
-  
        atm_dev = atm_dev_register("fs", &ops, -1, NULL);
        if (!atm_dev)
                goto err_out_free_fs_dev;
index f2511b42dba20de4954f79ba6c91555867e1146c..b22a9142b240677530dc06a6781e5590b17ecafc 100644 (file)
@@ -383,14 +383,12 @@ he_init_one(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent)
        }
        pci_set_drvdata(pci_dev, atm_dev);
 
-       he_dev = (struct he_dev *) kmalloc(sizeof(struct he_dev),
+       he_dev = kzalloc(sizeof(struct he_dev),
                                                        GFP_KERNEL);
        if (!he_dev) {
                err = -ENOMEM;
                goto init_one_failure;
        }
-       memset(he_dev, 0, sizeof(struct he_dev));
-
        he_dev->pci_dev = pci_dev;
        he_dev->atm_dev = atm_dev;
        he_dev->atm_dev->dev_data = he_dev;
index d1113e845f953bc6dc963215a5b9f37936062651..209dba1c70da530474afc0271fb01e36df2e8cea 100644 (file)
@@ -2719,7 +2719,7 @@ static int __devinit hrz_probe(struct pci_dev *pci_dev, const struct pci_device_
                goto out_disable;
        }
 
-       dev = kmalloc(sizeof(hrz_dev), GFP_KERNEL);
+       dev = kzalloc(sizeof(hrz_dev), GFP_KERNEL);
        if (!dev) {
                // perhaps we should be nice: deregister all adapters and abort?
                PRINTD(DBG_ERR, "out of memory");
@@ -2727,8 +2727,6 @@ static int __devinit hrz_probe(struct pci_dev *pci_dev, const struct pci_device_
                goto out_release;
        }
 
-       memset(dev, 0, sizeof(hrz_dev));
-
        pci_set_drvdata(pci_dev, dev);
 
        // grab IRQ and install handler - move this someplace more sensible
index b0369bb20f085043348600a47192298f94f48981..7487f0ad68e9cdd869e21e004227188b6d2ab2a9 100644 (file)
@@ -642,11 +642,9 @@ alloc_scq(struct idt77252_dev *card, int class)
 {
        struct scq_info *scq;
 
-       scq = (struct scq_info *) kmalloc(sizeof(struct scq_info), GFP_KERNEL);
+       scq = kzalloc(sizeof(struct scq_info), GFP_KERNEL);
        if (!scq)
                return NULL;
-       memset(scq, 0, sizeof(struct scq_info));
-
        scq->base = pci_alloc_consistent(card->pcidev, SCQ_SIZE,
                                         &scq->paddr);
        if (scq->base == NULL) {
@@ -2142,11 +2140,9 @@ idt77252_init_est(struct vc_map *vc, int pcr)
 {
        struct rate_estimator *est;
 
-       est = kmalloc(sizeof(struct rate_estimator), GFP_KERNEL);
+       est = kzalloc(sizeof(struct rate_estimator), GFP_KERNEL);
        if (!est)
                return NULL;
-       memset(est, 0, sizeof(*est));
-
        est->maxcps = pcr < 0 ? -pcr : pcr;
        est->cps = est->maxcps;
        est->avcps = est->cps << 5;
@@ -2451,14 +2447,12 @@ idt77252_open(struct atm_vcc *vcc)
 
        index = VPCI2VC(card, vpi, vci);
        if (!card->vcs[index]) {
-               card->vcs[index] = kmalloc(sizeof(struct vc_map), GFP_KERNEL);
+               card->vcs[index] = kzalloc(sizeof(struct vc_map), GFP_KERNEL);
                if (!card->vcs[index]) {
                        printk("%s: can't alloc vc in open()\n", card->name);
                        up(&card->mutex);
                        return -ENOMEM;
                }
-               memset(card->vcs[index], 0, sizeof(struct vc_map));
-
                card->vcs[index]->card = card;
                card->vcs[index]->index = index;
 
@@ -2926,13 +2920,11 @@ open_card_oam(struct idt77252_dev *card)
                for (vci = 3; vci < 5; vci++) {
                        index = VPCI2VC(card, vpi, vci);
 
-                       vc = kmalloc(sizeof(struct vc_map), GFP_KERNEL);
+                       vc = kzalloc(sizeof(struct vc_map), GFP_KERNEL);
                        if (!vc) {
                                printk("%s: can't alloc vc\n", card->name);
                                return -ENOMEM;
                        }
-                       memset(vc, 0, sizeof(struct vc_map));
-
                        vc->index = index;
                        card->vcs[index] = vc;
 
@@ -2995,12 +2987,11 @@ open_card_ubr0(struct idt77252_dev *card)
 {
        struct vc_map *vc;
 
-       vc = kmalloc(sizeof(struct vc_map), GFP_KERNEL);
+       vc = kzalloc(sizeof(struct vc_map), GFP_KERNEL);
        if (!vc) {
                printk("%s: can't alloc vc\n", card->name);
                return -ENOMEM;
        }
-       memset(vc, 0, sizeof(struct vc_map));
        card->vcs[0] = vc;
        vc->class = SCHED_UBR0;
 
@@ -3695,14 +3686,12 @@ idt77252_init_one(struct pci_dev *pcidev, const struct pci_device_id *id)
                goto err_out_disable_pdev;
        }
 
-       card = kmalloc(sizeof(struct idt77252_dev), GFP_KERNEL);
+       card = kzalloc(sizeof(struct idt77252_dev), GFP_KERNEL);
        if (!card) {
                printk("idt77252-%d: can't allocate private data\n", index);
                err = -ENOMEM;
                goto err_out_disable_pdev;
        }
-       memset(card, 0, sizeof(struct idt77252_dev));
-
        card->revision = revision;
        card->index = index;
        card->pcidev = pcidev;
index fe60a59b7fc02e103f8a31f31c0c4ca103166e5d..b9568e10965a068b7372860e38696cf4069e85ef 100644 (file)
@@ -1482,16 +1482,10 @@ static inline void vcc_table_deallocate(const struct lanai_dev *lanai)
 static inline struct lanai_vcc *new_lanai_vcc(void)
 {
        struct lanai_vcc *lvcc;
-       lvcc = (struct lanai_vcc *) kmalloc(sizeof(*lvcc), GFP_KERNEL);
+       lvcc =  kzalloc(sizeof(*lvcc), GFP_KERNEL);
        if (likely(lvcc != NULL)) {
-               lvcc->vbase = NULL;
-               lvcc->rx.atmvcc = lvcc->tx.atmvcc = NULL;
-               lvcc->nref = 0;
-               memset(&lvcc->stats, 0, sizeof lvcc->stats);
-               lvcc->rx.buf.start = lvcc->tx.buf.start = NULL;
                skb_queue_head_init(&lvcc->tx.backlog);
 #ifdef DEBUG
-               lvcc->tx.unqueue = NULL;
                lvcc->vci = -1;
 #endif
        }
index 2c65e82f0d6b855310cb8e4e95a8a5c8c27a47bb..083c5d3f2e1855d25a568174fa176a65269327a9 100644 (file)
@@ -603,9 +603,8 @@ static int start_rx(struct atm_dev *dev)
 DPRINTK("start_rx\n");
        zatm_dev = ZATM_DEV(dev);
        size = sizeof(struct atm_vcc *)*zatm_dev->chans;
-       zatm_dev->rx_map = (struct atm_vcc **) kmalloc(size,GFP_KERNEL);
+       zatm_dev->rx_map =  kzalloc(size,GFP_KERNEL);
        if (!zatm_dev->rx_map) return -ENOMEM;
-       memset(zatm_dev->rx_map,0,size);
        /* set VPI/VCI split (use all VCIs and give what's left to VPIs) */
        zpokel(zatm_dev,(1 << dev->ci_range.vci_bits)-1,uPD98401_VRR);
        /* prepare free buffer pools */
@@ -801,6 +800,7 @@ static int alloc_shaper(struct atm_dev *dev,int *pcr,int min,int max,int ubr)
                i = m = 1;
                zatm_dev->ubr_ref_cnt++;
                zatm_dev->ubr = shaper;
+               *pcr = 0;
        }
        else {
                if (min) {
@@ -951,9 +951,8 @@ static int open_tx_first(struct atm_vcc *vcc)
        skb_queue_head_init(&zatm_vcc->tx_queue);
        init_waitqueue_head(&zatm_vcc->tx_wait);
        /* initialize ring */
-       zatm_vcc->ring = kmalloc(RING_SIZE,GFP_KERNEL);
+       zatm_vcc->ring = kzalloc(RING_SIZE,GFP_KERNEL);
        if (!zatm_vcc->ring) return -ENOMEM;
-       memset(zatm_vcc->ring,0,RING_SIZE);
        loop = zatm_vcc->ring+RING_ENTRIES*RING_WORDS;
        loop[0] = uPD98401_TXPD_V;
        loop[1] = loop[2] = 0;
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 f2305ee792a142b32d700473222ffe530742f31b..fdc8f892eb866ddba508805816ba57a022d015b9 100644 (file)
@@ -636,7 +636,7 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        intr = in_8(&sw->intr);
        err = (intr & ERROR_INTR)? in_8(&sw->error): 0;
        if ((intr & ERROR_INTR) && fs->state != do_transfer)
-               printk(KERN_ERR "swim3_interrupt, state=%d, dir=%lx, intr=%x, err=%x\n",
+               printk(KERN_ERR "swim3_interrupt, state=%d, dir=%x, intr=%x, err=%x\n",
                       fs->state, rq_data_dir(fd_req), intr, err);
        switch (fs->state) {
        case locating:
@@ -742,7 +742,7 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                        if ((stat & ACTIVE) == 0 || resid != 0) {
                                /* musta been an error */
                                printk(KERN_ERR "swim3: fd dma: stat=%x resid=%d\n", stat, resid);
-                               printk(KERN_ERR "  state=%d, dir=%lx, intr=%x, err=%x\n",
+                               printk(KERN_ERR "  state=%d, dir=%x, intr=%x, err=%x\n",
                                       fs->state, rq_data_dir(fd_req), intr, err);
                                end_request(fd_req, 0);
                                fs->state = idle;
index 5d8925bd90454c68d33d00d3263e93dac09b91df..cbb9d0f21acc7d8f52dbdbacb499465172b36982 100644 (file)
@@ -552,7 +552,8 @@ static void process_page(unsigned long data)
 static int mm_make_request(request_queue_t *q, struct bio *bio)
 {
        struct cardinfo *card = q->queuedata;
-       pr_debug("mm_make_request %ld %d\n", bh->b_rsector, bh->b_size);
+       pr_debug("mm_make_request %llu %u\n",
+                (unsigned long long)bio->bi_sector, bio->bi_size);
 
        bio->bi_phys_segments = bio->bi_idx; /* count of completed segments*/
        spin_lock_irq(&card->lock);
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 73dfdcebfbba64a725a99fbb637242e07c1c5071..83683a2d8e6a9822ef2ee2f2a567b7600dea241f 100644 (file)
@@ -1,3 +1,2 @@
 consolemap_deftbl.c
 defkeymap.c
-qtronixmap.c
index bde1c665d9f4b1cf6e70cfa9ba32ec7bd765d3cc..0e6f35fcc2ebf9ed0fd36ddaa74c5faf3b8cedac 100644 (file)
@@ -371,36 +371,6 @@ config AU1000_SERIAL_CONSOLE
          If you have an Alchemy AU1000 processor (MIPS based) and you want
          to use a console on a serial port, say Y.  Otherwise, say N.
 
-config QTRONIX_KEYBOARD
-       bool "Enable Qtronix 990P Keyboard Support"
-       depends on IT8712
-       help
-         Images of Qtronix keyboards are at
-         <http://www.qtronix.com/keyboard.html>.
-
-config IT8172_CIR
-       bool
-       depends on QTRONIX_KEYBOARD
-       default y
-
-config IT8172_SCR0
-       bool "Enable Smart Card Reader 0 Support "
-       depends on IT8712
-       help
-         Say Y here to support smart-card reader 0 (SCR0) on the Integrated
-         Technology Express, Inc. ITE8172 SBC.  Vendor page at
-         <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
-         board at <http://www.mvista.com/partners/semiconductor/ite.html>.
-
-config IT8172_SCR1
-       bool "Enable Smart Card Reader 1 Support "
-       depends on IT8712
-       help
-         Say Y here to support smart-card reader 1 (SCR1) on the Integrated
-         Technology Express, Inc. ITE8172 SBC.  Vendor page at
-         <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
-         board at <http://www.mvista.com/partners/semiconductor/ite.html>.
-
 config A2232
        tristate "Commodore A2232 serial support (EXPERIMENTAL)"
        depends on EXPERIMENTAL && ZORRO && BROKEN_ON_SMP
index 19114df59bbdf72e973812808f66caaa65ca4df2..777cad045094672c0d1fe86f0fa2df3d15cb42c4 100644 (file)
@@ -102,7 +102,7 @@ obj-$(CONFIG_HANGCHECK_TIMER)       += hangcheck-timer.o
 obj-$(CONFIG_TCG_TPM)          += tpm/
 
 # Files generated that shall be removed upon make clean
-clean-files := consolemap_deftbl.c defkeymap.c qtronixmap.c
+clean-files := consolemap_deftbl.c defkeymap.c
 
 quiet_cmd_conmk = CONMK   $@
       cmd_conmk = scripts/conmakehash $< > $@
@@ -112,8 +112,6 @@ $(obj)/consolemap_deftbl.c: $(src)/$(FONTMAPFILE)
 
 $(obj)/defkeymap.o:  $(obj)/defkeymap.c
 
-$(obj)/qtronixmap.o: $(obj)/qtronixmap.c
-
 # Uncomment if you're changing the keymap and have an appropriate
 # loadkeys version for the map. By default, we'll use the shipped
 # versions.
@@ -121,7 +119,7 @@ $(obj)/qtronixmap.o: $(obj)/qtronixmap.c
 
 ifdef GENERATE_KEYMAP
 
-$(obj)/defkeymap.c $(obj)/qtronixmap.c: $(obj)/%.c: $(src)/%.map
+$(obj)/defkeymap.c $(obj)/%.c: $(src)/%.map
        loadkeys --mktable $< > $@.tmp
        sed -e 's/^static *//' $@.tmp > $@
        rm $@.tmp
index 22f8cf218cc6443a1af9f523ae49dfc47fe56340..c603bf2915803e0e9d243b6d82d5db317780b473 100644 (file)
@@ -1,6 +1,6 @@
 config AGP
        tristate "/dev/agpgart (AGP Support)"
-       depends on ALPHA || IA64 || PPC || X86
+       depends on ALPHA || IA64 || PARISC || PPC || X86
        depends on PCI
        ---help---
          AGP (Accelerated Graphics Port) is a bus system mainly used to
@@ -122,6 +122,14 @@ config AGP_HP_ZX1
          This option gives you AGP GART support for the HP ZX1 chipset
          for IA64 processors.
 
+config AGP_PARISC
+       tristate "HP Quicksilver AGP support"
+       depends on AGP && PARISC && 64BIT
+       help
+         This option gives you AGP GART support for the HP Quicksilver
+         AGP bus adapter on HP PA-RISC machines (Ok, just on the C8000
+         workstation...)
+
 config AGP_ALPHA_CORE
        tristate "Alpha AGP support"
        depends on AGP && (ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL)
index d33a22f2fa0b9b2fa509517789884e119294851f..3e581603d0a822b9bab9a95b2f55ae056ffb3b05 100644 (file)
@@ -8,6 +8,7 @@ obj-$(CONFIG_AGP_AMD64)         += amd64-agp.o
 obj-$(CONFIG_AGP_ALPHA_CORE)   += alpha-agp.o
 obj-$(CONFIG_AGP_EFFICEON)     += efficeon-agp.o
 obj-$(CONFIG_AGP_HP_ZX1)       += hp-agp.o
+obj-$(CONFIG_AGP_PARISC)       += parisc-agp.o
 obj-$(CONFIG_AGP_I460)         += i460-agp.o
 obj-$(CONFIG_AGP_INTEL)                += intel-agp.o
 obj-$(CONFIG_AGP_NVIDIA)       += nvidia-agp.o
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c
new file mode 100644 (file)
index 0000000..17c50b0
--- /dev/null
@@ -0,0 +1,416 @@
+/*
+ * HP Quicksilver AGP GART routines
+ *
+ * Copyright (c) 2006, Kyle McMartin <kyle@parisc-linux.org>
+ *
+ * Based on drivers/char/agpgart/hp-agp.c which is
+ * (c) Copyright 2002, 2003 Hewlett-Packard Development Company, L.P.
+ *     Bjorn Helgaas <bjorn.helgaas@hp.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/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/klist.h>
+#include <linux/agp_backend.h>
+
+#include <asm-parisc/parisc-device.h>
+#include <asm-parisc/ropes.h>
+
+#include "agp.h"
+
+#define DRVNAME        "quicksilver"
+#define DRVPFX DRVNAME ": "
+
+#ifndef log2
+#define log2(x)                ffz(~(x))
+#endif
+
+#define AGP8X_MODE_BIT         3
+#define AGP8X_MODE             (1 << AGP8X_MODE_BIT)
+
+static struct _parisc_agp_info {
+       void __iomem *ioc_regs;
+       void __iomem *lba_regs;
+
+       int lba_cap_offset;
+
+       u64 *gatt;
+       u64 gatt_entries;
+
+       u64 gart_base;
+       u64 gart_size;
+
+       int io_page_size;
+       int io_pages_per_kpage;
+} parisc_agp_info;
+
+static struct gatt_mask parisc_agp_masks[] =
+{
+        {
+               .mask = SBA_PDIR_VALID_BIT,
+               .type = 0
+       }
+};
+
+static struct aper_size_info_fixed parisc_agp_sizes[] =
+{
+        {0, 0, 0},              /* filled in by parisc_agp_fetch_size() */
+};
+
+static int
+parisc_agp_fetch_size(void)
+{
+       int size;
+
+       size = parisc_agp_info.gart_size / MB(1);
+       parisc_agp_sizes[0].size = size;
+       agp_bridge->current_size = (void *) &parisc_agp_sizes[0];
+
+       return size;
+}
+
+static int
+parisc_agp_configure(void)
+{
+       struct _parisc_agp_info *info = &parisc_agp_info;
+
+       agp_bridge->gart_bus_addr = info->gart_base;
+       agp_bridge->capndx = info->lba_cap_offset;
+       agp_bridge->mode = readl(info->lba_regs+info->lba_cap_offset+PCI_AGP_STATUS);
+
+       return 0;
+}
+
+static void
+parisc_agp_tlbflush(struct agp_memory *mem)
+{
+       struct _parisc_agp_info *info = &parisc_agp_info;
+
+       writeq(info->gart_base | log2(info->gart_size), info->ioc_regs+IOC_PCOM);
+       readq(info->ioc_regs+IOC_PCOM); /* flush */
+}
+
+static int
+parisc_agp_create_gatt_table(struct agp_bridge_data *bridge)
+{
+       struct _parisc_agp_info *info = &parisc_agp_info;
+       int i;
+
+       for (i = 0; i < info->gatt_entries; i++) {
+               info->gatt[i] = (unsigned long)agp_bridge->scratch_page;
+       }
+
+       return 0;
+}
+
+static int
+parisc_agp_free_gatt_table(struct agp_bridge_data *bridge)
+{
+       struct _parisc_agp_info *info = &parisc_agp_info;
+
+       info->gatt[0] = SBA_AGPGART_COOKIE;
+
+       return 0;
+}
+
+static int
+parisc_agp_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
+{
+       struct _parisc_agp_info *info = &parisc_agp_info;
+       int i, k;
+       off_t j, io_pg_start;
+       int io_pg_count;
+
+       if (type != 0 || mem->type != 0) {
+               return -EINVAL;
+       }
+
+       io_pg_start = info->io_pages_per_kpage * pg_start;
+       io_pg_count = info->io_pages_per_kpage * mem->page_count;
+       if ((io_pg_start + io_pg_count) > info->gatt_entries) {
+               return -EINVAL;
+       }
+
+       j = io_pg_start;
+       while (j < (io_pg_start + io_pg_count)) {
+               if (info->gatt[j])
+                       return -EBUSY;
+               j++;
+       }
+
+       if (mem->is_flushed == FALSE) {
+               global_cache_flush();
+               mem->is_flushed = TRUE;
+       }
+
+       for (i = 0, j = io_pg_start; i < mem->page_count; i++) {
+               unsigned long paddr;
+
+               paddr = mem->memory[i];
+               for (k = 0;
+                    k < info->io_pages_per_kpage;
+                    k++, j++, paddr += info->io_page_size) {
+                       info->gatt[j] =
+                               agp_bridge->driver->mask_memory(agp_bridge,
+                                       paddr, type);
+               }
+       }
+
+       agp_bridge->driver->tlb_flush(mem);
+
+       return 0;
+}
+
+static int
+parisc_agp_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
+{
+       struct _parisc_agp_info *info = &parisc_agp_info;
+       int i, io_pg_start, io_pg_count;
+
+       if (type != 0 || mem->type != 0) {
+               return -EINVAL;
+       }
+
+       io_pg_start = info->io_pages_per_kpage * pg_start;
+       io_pg_count = info->io_pages_per_kpage * mem->page_count;
+       for (i = io_pg_start; i < io_pg_count + io_pg_start; i++) {
+               info->gatt[i] = agp_bridge->scratch_page;
+       }
+
+       agp_bridge->driver->tlb_flush(mem);
+       return 0;
+}
+
+static unsigned long
+parisc_agp_mask_memory(struct agp_bridge_data *bridge,
+                   unsigned long addr, int type)
+{
+       return SBA_PDIR_VALID_BIT | addr;
+}
+
+static void
+parisc_agp_enable(struct agp_bridge_data *bridge, u32 mode)
+{
+       struct _parisc_agp_info *info = &parisc_agp_info;
+       u32 command;
+
+       command = readl(info->lba_regs + info->lba_cap_offset + PCI_AGP_STATUS);
+
+       command = agp_collect_device_status(bridge, mode, command);
+       command |= 0x00000100;
+
+       writel(command, info->lba_regs + info->lba_cap_offset + PCI_AGP_COMMAND);
+
+       agp_device_command(command, (mode & AGP8X_MODE) != 0);
+}
+
+struct agp_bridge_driver parisc_agp_driver = {
+       .owner                  = THIS_MODULE,
+       .size_type              = FIXED_APER_SIZE,
+       .configure              = parisc_agp_configure,
+       .fetch_size             = parisc_agp_fetch_size,
+       .tlb_flush              = parisc_agp_tlbflush,
+       .mask_memory            = parisc_agp_mask_memory,
+       .masks                  = parisc_agp_masks,
+       .agp_enable             = parisc_agp_enable,
+       .cache_flush            = global_cache_flush,
+       .create_gatt_table      = parisc_agp_create_gatt_table,
+       .free_gatt_table        = parisc_agp_free_gatt_table,
+       .insert_memory          = parisc_agp_insert_memory,
+       .remove_memory          = parisc_agp_remove_memory,
+       .alloc_by_type          = agp_generic_alloc_by_type,
+       .free_by_type           = agp_generic_free_by_type,
+       .agp_alloc_page         = agp_generic_alloc_page,
+       .agp_destroy_page       = agp_generic_destroy_page,
+       .cant_use_aperture      = 1,
+};
+
+static int __init
+agp_ioc_init(void __iomem *ioc_regs)
+{
+       struct _parisc_agp_info *info = &parisc_agp_info;
+        u64 *iova_base, *io_pdir, io_tlb_ps;
+        int io_tlb_shift;
+
+        printk(KERN_INFO DRVPFX "IO PDIR shared with sba_iommu\n");
+
+        info->ioc_regs = ioc_regs;
+
+        io_tlb_ps = readq(info->ioc_regs+IOC_TCNFG);
+        switch (io_tlb_ps) {
+        case 0: io_tlb_shift = 12; break;
+        case 1: io_tlb_shift = 13; break;
+        case 2: io_tlb_shift = 14; break;
+        case 3: io_tlb_shift = 16; break;
+        default:
+                printk(KERN_ERR DRVPFX "Invalid IOTLB page size "
+                       "configuration 0x%llx\n", io_tlb_ps);
+                info->gatt = NULL;
+                info->gatt_entries = 0;
+                return -ENODEV;
+        }
+        info->io_page_size = 1 << io_tlb_shift;
+        info->io_pages_per_kpage = PAGE_SIZE / info->io_page_size;
+
+        iova_base = readq(info->ioc_regs+IOC_IBASE) & ~0x1;
+        info->gart_base = iova_base + PLUTO_IOVA_SIZE - PLUTO_GART_SIZE;
+
+        info->gart_size = PLUTO_GART_SIZE;
+        info->gatt_entries = info->gart_size / info->io_page_size;
+
+        io_pdir = phys_to_virt(readq(info->ioc_regs+IOC_PDIR_BASE));
+        info->gatt = &io_pdir[(PLUTO_IOVA_SIZE/2) >> PAGE_SHIFT];
+
+        if (info->gatt[0] != SBA_AGPGART_COOKIE) {
+                info->gatt = NULL;
+                info->gatt_entries = 0;
+                printk(KERN_ERR DRVPFX "No reserved IO PDIR entry found; "
+                       "GART disabled\n");
+                return -ENODEV;
+        }
+
+        return 0;
+}
+
+static int
+lba_find_capability(int cap)
+{
+       struct _parisc_agp_info *info = &parisc_agp_info;
+        u16 status;
+        u8 pos, id;
+        int ttl = 48;
+
+        status = readw(info->lba_regs + PCI_STATUS);
+        if (!(status & PCI_STATUS_CAP_LIST))
+                return 0;
+        pos = readb(info->lba_regs + PCI_CAPABILITY_LIST);
+        while (ttl-- && pos >= 0x40) {
+                pos &= ~3;
+                id = readb(info->lba_regs + pos + PCI_CAP_LIST_ID);
+                if (id == 0xff)
+                        break;
+                if (id == cap)
+                        return pos;
+                pos = readb(info->lba_regs + pos + PCI_CAP_LIST_NEXT);
+        }
+        return 0;
+}
+
+static int __init
+agp_lba_init(void __iomem *lba_hpa)
+{
+       struct _parisc_agp_info *info = &parisc_agp_info;
+        int cap;
+
+       info->lba_regs = lba_hpa;
+        info->lba_cap_offset = lba_find_capability(PCI_CAP_ID_AGP);
+
+        cap = readl(lba_hpa + info->lba_cap_offset) & 0xff;
+        if (cap != PCI_CAP_ID_AGP) {
+                printk(KERN_ERR DRVPFX "Invalid capability ID 0x%02x at 0x%x\n",
+                       cap, info->lba_cap_offset);
+                return -ENODEV;
+        }
+
+        return 0;
+}
+
+static int __init
+parisc_agp_setup(void __iomem *ioc_hpa, void __iomem *lba_hpa)
+{
+       struct pci_dev *fake_bridge_dev = NULL;
+       struct agp_bridge_data *bridge;
+       int error = 0;
+
+       fake_bridge_dev = kmalloc(sizeof (struct pci_dev), GFP_KERNEL);
+       if (!fake_bridge_dev) {
+               error = -ENOMEM;
+               goto fail;
+       }
+
+       error = agp_ioc_init(ioc_hpa);
+       if (error)
+               goto fail;
+
+       error = agp_lba_init(lba_hpa);
+       if (error)
+               goto fail;
+
+       bridge = agp_alloc_bridge();
+       if (!bridge) {
+               error = -ENOMEM;
+               goto fail;
+       }
+       bridge->driver = &parisc_agp_driver;
+
+       fake_bridge_dev->vendor = PCI_VENDOR_ID_HP;
+       fake_bridge_dev->device = PCI_DEVICE_ID_HP_PCIX_LBA;
+       bridge->dev = fake_bridge_dev;
+
+       error = agp_add_bridge(bridge);
+
+fail:
+       return error;
+}
+
+static struct device *next_device(struct klist_iter *i) {
+       struct klist_node * n = klist_next(i);
+       return n ? container_of(n, struct device, knode_parent) : NULL;
+}
+
+static int
+parisc_agp_init(void)
+{
+       extern struct sba_device *sba_list;
+
+       int err = -1;
+       struct parisc_device *sba = NULL, *lba = NULL;
+       struct lba_device *lbadev = NULL;
+       struct device *dev = NULL;
+       struct klist_iter i;
+
+       if (!sba_list)
+               goto out;
+
+       /* Find our parent Pluto */
+       sba = sba_list->dev;
+       if (!IS_PLUTO(sba)) {
+               printk(KERN_INFO DRVPFX "No Pluto found, so no AGPGART for you.\n");
+               goto out;
+       }
+
+       /* Now search our Pluto for our precious AGP device... */
+       klist_iter_init(&sba->dev.klist_children, &i);
+       while ((dev = next_device(&i))) {
+               struct parisc_device *padev = to_parisc_device(dev);
+               if (IS_QUICKSILVER(padev))
+                       lba = padev;
+       }
+       klist_iter_exit(&i);
+
+       if (!lba) {
+               printk(KERN_INFO DRVPFX "No AGP devices found.\n");
+               goto out;
+       }
+
+       lbadev = parisc_get_drvdata(lba);
+
+       /* w00t, let's go find our cookies... */
+       parisc_agp_setup(sba_list->ioc[0].ioc_hpa, lbadev->hba.base_addr);
+
+       return 0;
+
+out:
+       return err;
+}
+
+module_init(parisc_agp_init);
+
+MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>");
+MODULE_LICENSE("GPL");
index 9d6713a93ed74ddb74adaf18aa85fd22e0ee6508..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
         */
@@ -1958,7 +1935,7 @@ static void show_serial_version(void)
 }
 
 
-static struct tty_operations serial_ops = {
+static const struct tty_operations serial_ops = {
        .open = rs_open,
        .close = rs_close,
        .write = rs_write,
@@ -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 c1c67281750da61ef1750706bb8351e780cb3e43..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);
@@ -5205,7 +5183,7 @@ done:
     extra ports are ignored.
  */
 
-static struct tty_operations cy_ops = {
+static const struct tty_operations cy_ops = {
     .open = cy_open,
     .close = cy_close,
     .write = cy_write,
@@ -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 86d290e9f307044041fed353cf6bca3ed0cc44cc..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);
@@ -1125,7 +1122,7 @@ static void __exit epca_module_exit(void)
 
 module_exit(epca_module_exit);
 
-static struct tty_operations pc_ops = {
+static const struct tty_operations pc_ops = {
        .open = pc_open,
        .close = pc_close,
        .write = pc_write,
@@ -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 afcd83d9984be5b00937c7959d3bc7476ec2041c..05788c75d7fc83dffc807c5e654cae160a469959 100644 (file)
@@ -2376,7 +2376,7 @@ static inline int autoconfig(struct esp_struct * info)
        return (port_detected);
 }
 
-static struct tty_operations esp_ops = {
+static const struct tty_operations esp_ops = {
        .open = esp_open,
        .close = rs_close,
        .write = rs_write,
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 a76d2c40dd5e7e5e375a9a39054333c3752fdafa..4053d1cd393f520101857047d52fc63b70efe7d7 100644 (file)
@@ -696,7 +696,7 @@ int khvcd(void *unused)
        return 0;
 }
 
-static struct tty_operations hvc_ops = {
+static const struct tty_operations hvc_ops = {
        .open = hvc_open,
        .close = hvc_close,
        .write = hvc_write,
index 4747729459c7a5a0c0aa29f9ec8a7023d73fc66a..f144a947bd17aaa8549230e307c13def30296822 100644 (file)
@@ -29,6 +29,7 @@
 #include <asm/hvconsole.h>
 #include <asm/vio.h>
 #include <asm/prom.h>
+#include <asm/firmware.h>
 #include <asm/iseries/vio.h>
 #include <asm/iseries/hv_call.h>
 #include <asm/iseries/hv_lp_config.h>
@@ -153,9 +154,7 @@ static int put_chars(uint32_t vtermno, const char *buf, int count)
        spin_lock_irqsave(&consolelock, flags);
 
        if (viochar_is_console(pi) && !viopath_isactive(pi->lp)) {
-               spin_lock_irqsave(&consoleloglock, flags);
                HvCall_writeLogBuffer(buf, count);
-               spin_unlock_irqrestore(&consoleloglock, flags);
                sent = count;
                goto done;
        }
@@ -171,11 +170,8 @@ static int put_chars(uint32_t vtermno, const char *buf, int count)
 
                len = (count > VIOCHAR_MAX_DATA) ? VIOCHAR_MAX_DATA : count;
 
-               if (viochar_is_console(pi)) {
-                       spin_lock_irqsave(&consoleloglock, flags);
+               if (viochar_is_console(pi))
                        HvCall_writeLogBuffer(buf, len);
-                       spin_unlock_irqrestore(&consoleloglock, flags);
-               }
 
                init_data_event(viochar, pi->lp);
 
@@ -493,6 +489,9 @@ static int hvc_vio_init(void)
        atomic_t wait_flag;
        int rc;
 
+       if (!firmware_has_feature(FW_FEATURE_ISERIES))
+               return -EIO;
+
        /* +2 for fudge */
        rc = viopath_open(HvLpConfig_getPrimaryLpIndex(),
                        viomajorsubtype_chario, VIOCHAR_WINDOW + 2);
@@ -567,7 +566,7 @@ static int hvc_find_vtys(void)
 
        for (vty = of_find_node_by_name(NULL, "vty"); vty != NULL;
                        vty = of_find_node_by_name(vty, "vty")) {
-               uint32_t *vtermno;
+               const uint32_t *vtermno;
 
                /* We have statically defined space for only a certain number
                 * of console adapters.
@@ -576,7 +575,7 @@ static int hvc_find_vtys(void)
                                (num_found >= VTTY_PORTS))
                        break;
 
-               vtermno = (uint32_t *)get_property(vty, "reg", NULL);
+               vtermno = get_property(vty, "reg", NULL);
                if (!vtermno)
                        continue;
 
index cc95941148fbfe2d824200413f58f08fcb3baafb..f9c00844d2bfe9250448e0436421085f4b220d8a 100644 (file)
@@ -35,6 +35,7 @@
 #include <asm/hvconsole.h>
 #include <asm/vio.h>
 #include <asm/prom.h>
+#include <asm/firmware.h>
 
 #include "hvc_console.h"
 
@@ -120,6 +121,9 @@ static int hvc_vio_init(void)
 {
        int rc;
 
+       if (firmware_has_feature(FW_FEATURE_ISERIES))
+               return -EIO;
+
        /* Register as a vio device to receive callbacks */
        rc = vio_register_driver(&hvc_vio_driver);
 
index 4589ff302b076a123396bd5d218aa6007a08d294..0b89bcde8c52e80c6550e96d42ed9503c91f1a99 100644 (file)
@@ -1306,7 +1306,7 @@ static int hvcs_chars_in_buffer(struct tty_struct *tty)
        return hvcsd->chars_in_buffer;
 }
 
-static struct tty_operations hvcs_ops = {
+static const struct tty_operations hvcs_ops = {
        .open = hvcs_open,
        .close = hvcs_close,
        .hangup = hvcs_hangup,
index a89a95fb5e40fb76b766c8b50483bd435ac2bd5e..c07dc58d5c1d7261eb6a4b75f9f935d3bf61ce72 100644 (file)
@@ -1130,7 +1130,7 @@ static int hvsi_tiocmset(struct tty_struct *tty, struct file *file,
 }
 
 
-static struct tty_operations hvsi_ops = {
+static const struct tty_operations hvsi_ops = {
        .open = hvsi_open,
        .close = hvsi_close,
        .write = hvsi_write,
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 331f447e62283291b3d799a04557ecb018a0d197..62ef511d143bf92888beffddf3441d2fc9460677 100644 (file)
@@ -458,7 +458,7 @@ cleanup_module(void)
 }
 #endif /* MODULE */
 
-static struct tty_operations ip2_ops = {
+static const struct tty_operations ip2_ops = {
        .open            = ip2_open,
        .close           = ip2_close,
        .write           = ip2_write,
@@ -779,8 +779,6 @@ retry:
        ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0 );
        goto out;
 
-out_class:
-       class_destroy(ip2_class);
 out_chrdev:
        unregister_chrdev(IP2_IPL_MAJOR, "ip2");
 out:
index 908521e36d81ca137abdce89f0c09e2475d1af30..b106c45abfc927f359ae463ad8659cd2f2cdf7e7 100644 (file)
@@ -217,6 +217,11 @@ struct smi_info
        struct list_head link;
 };
 
+#define SI_MAX_PARMS 4
+
+static int force_kipmid[SI_MAX_PARMS];
+static int num_force_kipmid;
+
 static int try_smi_init(struct smi_info *smi);
 
 static ATOMIC_NOTIFIER_HEAD(xaction_notifier_list);
@@ -908,6 +913,7 @@ static int smi_start_processing(void       *send_info,
                                ipmi_smi_t intf)
 {
        struct smi_info *new_smi = send_info;
+       int             enable = 0;
 
        new_smi->intf = intf;
 
@@ -916,11 +922,19 @@ static int smi_start_processing(void       *send_info,
        new_smi->last_timeout_jiffies = jiffies;
        mod_timer(&new_smi->si_timer, jiffies + SI_TIMEOUT_JIFFIES);
 
+       /*
+        * Check if the user forcefully enabled the daemon.
+        */
+       if (new_smi->intf_num < num_force_kipmid)
+               enable = force_kipmid[new_smi->intf_num];
        /*
         * The BT interface is efficient enough to not need a thread,
         * and there is no need for a thread if we have interrupts.
         */
-       if ((new_smi->si_type != SI_BT) && (!new_smi->irq)) {
+       else if ((new_smi->si_type != SI_BT) && (!new_smi->irq))
+               enable = 1;
+
+       if (enable) {
                new_smi->thread = kthread_run(ipmi_thread, new_smi,
                                              "kipmi%d", new_smi->intf_num);
                if (IS_ERR(new_smi->thread)) {
@@ -948,7 +962,6 @@ static struct ipmi_smi_handlers handlers =
 /* There can be 4 IO ports passed in (with or without IRQs), 4 addresses,
    a default IO port, and 1 ACPI/SPMI address.  That sets SI_MAX_DRIVERS */
 
-#define SI_MAX_PARMS 4
 static LIST_HEAD(smi_infos);
 static DEFINE_MUTEX(smi_infos_lock);
 static int smi_num; /* Used to sequence the SMIs */
@@ -1021,6 +1034,10 @@ MODULE_PARM_DESC(slave_addrs, "Set the default IPMB slave address for"
                 " the controller.  Normally this is 0x20, but can be"
                 " overridden by this parm.  This is an array indexed"
                 " by interface number.");
+module_param_array(force_kipmid, int, &num_force_kipmid, 0);
+MODULE_PARM_DESC(force_kipmid, "Force the kipmi daemon to be enabled (1) or"
+                " disabled(0).  Normally the IPMI driver auto-detects"
+                " this, but the value may be overridden by this parm.");
 
 
 #define IPMI_IO_ADDR_SPACE  0
@@ -1734,6 +1751,7 @@ static void __devinit dmi_find_bmc(void)
        int                  rv;
 
        while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev))) {
+               memset(&data, 0, sizeof(data));
                rv = decode_dmi((struct dmi_header *) dev->device_data, &data);
                if (!rv)
                        try_init_dmi(&data);
index 2e1da632aee18ef3c8d7ea22cc70ea06010169b5..ea2bbf80ad33839b381bb526ab957dd540e55b8a 100644 (file)
@@ -1550,7 +1550,7 @@ static void isicom_unregister_ioregion(struct pci_dev *pdev)
        board->base = 0;
 }
 
-static struct tty_operations isicom_ops = {
+static const struct tty_operations isicom_ops = {
        .open                   = isicom_open,
        .close                  = isicom_close,
        .write                  = isicom_write,
index 6b4d82a4565fbf9ec533891f8043b6aa3d5ca707..d6e031542c6bdbd68932b3a46c7fa3ccaf1d2925 100644 (file)
@@ -4636,7 +4636,7 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un
        return rc;
 }
 
-static struct tty_operations stli_ops = {
+static const struct tty_operations stli_ops = {
        .open = stli_open,
        .close = stli_close,
        .write = stli_write,
diff --git a/drivers/char/ite_gpio.c b/drivers/char/ite_gpio.c
deleted file mode 100644 (file)
index cde562d..0000000
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * FILE NAME ite_gpio.c
- *
- * BRIEF MODULE DESCRIPTION
- *  API for ITE GPIO device.
- *  Driver for ITE GPIO device.
- *
- *  Author: MontaVista Software, Inc.  <source@mvista.com>
- *          Hai-Pao Fan <haipao@mvista.com>
- *
- * Copyright 2001 MontaVista Software Inc.
- *
- *  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.
- */
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/miscdevice.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <asm/uaccess.h>
-#include <asm/addrspace.h>
-#include <asm/it8172/it8172_int.h>
-#include <linux/sched.h>
-#include <linux/ite_gpio.h>
-
-#define ite_gpio_base 0x14013800
-
-#define        ITE_GPADR       (*(volatile __u8 *)(0x14013800 + KSEG1))
-#define        ITE_GPBDR       (*(volatile __u8 *)(0x14013808 + KSEG1))
-#define        ITE_GPCDR       (*(volatile __u8 *)(0x14013810 + KSEG1))
-#define        ITE_GPACR       (*(volatile __u16 *)(0x14013802 + KSEG1))
-#define        ITE_GPBCR       (*(volatile __u16 *)(0x1401380a + KSEG1))
-#define        ITE_GPCCR       (*(volatile __u16 *)(0x14013812 + KSEG1))
-#define ITE_GPAICR     (*(volatile __u16 *)(0x14013804 + KSEG1))
-#define        ITE_GPBICR      (*(volatile __u16 *)(0x1401380c + KSEG1))
-#define        ITE_GPCICR      (*(volatile __u16 *)(0x14013814 + KSEG1))
-#define        ITE_GPAISR      (*(volatile __u8 *)(0x14013806 + KSEG1))
-#define        ITE_GPBISR      (*(volatile __u8 *)(0x1401380e + KSEG1))
-#define        ITE_GPCISR      (*(volatile __u8 *)(0x14013816 + KSEG1))
-#define        ITE_GCR         (*(volatile __u8 *)(0x14013818 + KSEG1))
-
-#define MAX_GPIO_LINE          21
-static int ite_gpio_irq=IT8172_GPIO_IRQ;
-
-static long ite_irq_counter[MAX_GPIO_LINE];
-wait_queue_head_t ite_gpio_wait[MAX_GPIO_LINE];
-static int ite_gpio_irq_pending[MAX_GPIO_LINE];
-
-static int ite_gpio_debug=0;
-#define DEB(x)  if (ite_gpio_debug>=1) x
-
-int ite_gpio_in(__u32 device, __u32 mask, volatile __u32 *data)
-{
-       DEB(printk("ite_gpio_in mask=0x%x\n",mask)); 
-
-       switch (device) {
-       case ITE_GPIO_PORTA:
-               ITE_GPACR = (__u16)mask;        /* 0xffff */
-               *data = ITE_GPADR;
-               break;
-       case ITE_GPIO_PORTB:
-               ITE_GPBCR = (__u16)mask;        /* 0xffff */
-               *data = ITE_GPBDR;
-               break;
-       case ITE_GPIO_PORTC:
-               ITE_GPCCR = (__u16)mask;        /* 0x03ff */
-               *data = ITE_GPCDR;
-               break;
-       default:
-               return -EFAULT;
-       }
-
-       return 0;
-}
-
-
-int ite_gpio_out(__u32 device, __u32 mask, __u32 data)
-{
-       switch (device) {
-       case ITE_GPIO_PORTA:
-               ITE_GPACR = (__u16)mask;        /* 0x5555 */
-               ITE_GPADR = (__u8)data;
-               break;
-       case ITE_GPIO_PORTB:
-               ITE_GPBCR = (__u16)mask;        /* 0x5555 */
-               ITE_GPBDR = (__u8)data;
-               break;
-       case ITE_GPIO_PORTC:
-               ITE_GPCCR = (__u16)mask;        /* 0x0155 */
-               ITE_GPCDR = (__u8)data;
-               break;
-       default:
-               return -EFAULT;
-       }
-
-       return 0;
-}
-
-int ite_gpio_int_ctrl(__u32 device, __u32 mask, __u32 data)
-{
-       switch (device) {
-       case ITE_GPIO_PORTA:
-               ITE_GPAICR = (ITE_GPAICR & ~mask) | (data & mask);
-               break;
-       case ITE_GPIO_PORTB:
-               ITE_GPBICR = (ITE_GPBICR & ~mask) | (data & mask);
-               break;
-       case ITE_GPIO_PORTC:
-               ITE_GPCICR = (ITE_GPCICR & ~mask) | (data & mask);
-               break;
-       default:
-               return -EFAULT;
-       }
-
-       return 0;
-}
-
-int ite_gpio_in_status(__u32 device, __u32 mask, volatile __u32 *data)
-{
-       int ret=-1;
-
-       if ((MAX_GPIO_LINE > *data) && (*data >= 0)) 
-               ret=ite_gpio_irq_pending[*data];
-       DEB(printk("ite_gpio_in_status %d ret=%d\n",*data, ret));
-
-       switch (device) {
-       case ITE_GPIO_PORTA:
-               *data = ITE_GPAISR & mask;
-               break;
-       case ITE_GPIO_PORTB:
-               *data = ITE_GPBISR & mask;
-               break;
-       case ITE_GPIO_PORTC:
-               *data = ITE_GPCISR & mask;
-               break;
-       default:
-               return -EFAULT;
-       }
-
-       return ret;
-}
-
-int ite_gpio_out_status(__u32 device, __u32 mask, __u32 data)
-{
-       switch (device) {
-       case ITE_GPIO_PORTA:
-               ITE_GPAISR = (ITE_GPAISR & ~mask) | (data & mask);
-               break;
-       case ITE_GPIO_PORTB:
-               ITE_GPBISR = (ITE_GPBISR & ~mask) | (data & mask);
-               break;
-       case ITE_GPIO_PORTC:
-               ITE_GPCISR = (ITE_GPCISR & ~mask) | (data & mask);
-               break;
-       default:
-               return -EFAULT;
-       }
-
-       return 0;
-}
-
-int ite_gpio_gen_ctrl(__u32 device, __u32 mask, __u32 data)
-{
-       ITE_GCR = (ITE_GCR & ~mask) | (data & mask);
-
-       return 0;
-}
-
-int ite_gpio_int_wait (__u32 device, __u32 mask, __u32 data)
-{
-       int i,line=0, ret=0;
-       unsigned long flags;
-
-       switch (device) {
-       case ITE_GPIO_PORTA:
-               line = data & mask;
-               break;
-       case ITE_GPIO_PORTB:
-               line = (data & mask) <<8;
-               break;
-       case ITE_GPIO_PORTC:
-               line = (data & mask) <<16;
-               break;
-       }
-       for (i=MAX_GPIO_LINE-1; i >= 0; i--) {
-               if ( (line) & (1 << i))
-                       break;
-       }
-
-       DEB(printk("wait device=0x%d mask=0x%x data=0x%x index %d\n", 
-               device, mask, data, i));
-
-       if (line & ~(1<<i))
-               return -EFAULT;
-
-       if (ite_gpio_irq_pending[i]==1)
-               return -EFAULT;
-
-       save_flags (flags);
-       cli();
-       ite_gpio_irq_pending[i] = 1;
-       ret = interruptible_sleep_on_timeout(&ite_gpio_wait[i], 3*HZ);
-       restore_flags (flags);
-       ite_gpio_irq_pending[i] = 0;
-
-       return ret;
-}
-
-EXPORT_SYMBOL(ite_gpio_in);
-EXPORT_SYMBOL(ite_gpio_out);
-EXPORT_SYMBOL(ite_gpio_int_ctrl);
-EXPORT_SYMBOL(ite_gpio_in_status);
-EXPORT_SYMBOL(ite_gpio_out_status);
-EXPORT_SYMBOL(ite_gpio_gen_ctrl);
-EXPORT_SYMBOL(ite_gpio_int_wait);
-
-static int ite_gpio_open(struct inode *inode, struct file *file)
-{
-       return 0;
-}
-
-
-static int ite_gpio_release(struct inode *inode, struct file *file)
-{
-       return 0;
-}
-
-
-static int ite_gpio_ioctl(struct inode *inode, struct file *file,
-       unsigned int cmd, unsigned long arg)
-{
-       static struct ite_gpio_ioctl_data ioctl_data;
-
-       if (copy_from_user(&ioctl_data, (struct ite_gpio_ioctl_data *)arg,
-                       sizeof(ioctl_data)))
-               return -EFAULT;
-       if ((ioctl_data.device < ITE_GPIO_PORTA) ||
-                       (ioctl_data.device > ITE_GPIO_PORTC) )
-                               return -EFAULT;
-
-       switch(cmd) {
-               case ITE_GPIO_IN:
-                       if (ite_gpio_in(ioctl_data.device, ioctl_data.mask,
-                                          &ioctl_data.data))
-                               return -EFAULT;
-
-                       if (copy_to_user((struct ite_gpio_ioctl_data *)arg,
-                                        &ioctl_data, sizeof(ioctl_data)))
-                               return -EFAULT;
-                       break;
-
-               case ITE_GPIO_OUT:
-                       return ite_gpio_out(ioctl_data.device,
-                                       ioctl_data.mask, ioctl_data.data);
-                       break;
-
-               case ITE_GPIO_INT_CTRL:
-                       return ite_gpio_int_ctrl(ioctl_data.device,
-                                       ioctl_data.mask, ioctl_data.data);
-                       break;
-
-               case ITE_GPIO_IN_STATUS:
-                       if (ite_gpio_in_status(ioctl_data.device, ioctl_data.mask,
-                                       &ioctl_data.data))
-                               return -EFAULT;
-                       if (copy_to_user((struct ite_gpio_ioctl_data *)arg,
-                                       &ioctl_data, sizeof(ioctl_data))) 
-                               return -EFAULT;
-                       break;
-
-               case ITE_GPIO_OUT_STATUS:
-                       return ite_gpio_out_status(ioctl_data.device,
-                                       ioctl_data.mask, ioctl_data.data);
-                       break;
-
-               case ITE_GPIO_GEN_CTRL:
-                       return ite_gpio_gen_ctrl(ioctl_data.device,
-                                       ioctl_data.mask, ioctl_data.data);
-                       break;
-
-               case ITE_GPIO_INT_WAIT:
-                       return ite_gpio_int_wait(ioctl_data.device,
-                                       ioctl_data.mask, ioctl_data.data);
-                       break;
-
-               default:
-                       return -ENOIOCTLCMD;
-
-       }
-
-       return 0;
-}
-
-static void ite_gpio_irq_handler(int this_irq, void *dev_id,
-       struct pt_regs *regs)
-{
-       int i,line;
-
-       line = ITE_GPCISR & 0x1f;
-       for (i=4; i >=0; i--) {
-               if ( line & (1 << i)) { 
-                       ++ite_irq_counter[i+16];
-                       ite_gpio_irq_pending[i+16] = 2;
-                       wake_up_interruptible(&ite_gpio_wait[i+16]);
-
-DEB(printk("interrupt 0x%x %d\n", &ite_gpio_wait[i+16], i+16));
-
-                       ITE_GPCISR = ITE_GPCISR & (1<<i);
-                       return;
-               }
-       }
-       line = ITE_GPBISR;
-       for (i=7; i >= 0; i--) {
-               if ( line & (1 << i)) {
-                       ++ite_irq_counter[i+8];
-                       ite_gpio_irq_pending[i+8] = 2;
-                       wake_up_interruptible(&ite_gpio_wait[i+8]);
-
-DEB(printk("interrupt 0x%x %d\n",ITE_GPBISR, i+8));
-
-                       ITE_GPBISR = ITE_GPBISR & (1<<i);
-                       return;
-               }
-       }
-       line = ITE_GPAISR;
-       for (i=7; i >= 0; i--) {
-               if ( line & (1 << i)) {
-                       ++ite_irq_counter[i];
-                       ite_gpio_irq_pending[i] = 2;
-                       wake_up_interruptible(&ite_gpio_wait[i]);
-
-DEB(printk("interrupt 0x%x %d\n",ITE_GPAISR, i));
-
-                       ITE_GPAISR = ITE_GPAISR & (1<<i);
-                       return;
-               }
-       }
-}
-
-static const struct file_operations ite_gpio_fops = {
-       .owner          = THIS_MODULE,
-       .ioctl          = ite_gpio_ioctl,
-       .open           = ite_gpio_open,
-       .release        = ite_gpio_release,
-};
-
-static struct miscdevice ite_gpio_miscdev = {
-       MISC_DYNAMIC_MINOR,
-       "ite_gpio",
-       &ite_gpio_fops
-};
-
-int __init ite_gpio_init(void)
-{
-       int i;
-
-       if (misc_register(&ite_gpio_miscdev))
-               return -ENODEV;
-
-       if (!request_region(ite_gpio_base, 0x1c, "ITE GPIO"))
-       {
-               misc_deregister(&ite_gpio_miscdev);
-               return -EIO;
-       }
-
-       /* initialize registers */
-        ITE_GPACR = 0xffff;
-        ITE_GPBCR = 0xffff;
-        ITE_GPCCR = 0xffff;
-        ITE_GPAICR = 0x00ff;
-        ITE_GPBICR = 0x00ff;
-        ITE_GPCICR = 0x00ff;
-        ITE_GCR = 0;
-       
-       for (i = 0; i < MAX_GPIO_LINE; i++) {
-               ite_gpio_irq_pending[i]=0;      
-               init_waitqueue_head(&ite_gpio_wait[i]);
-       }
-
-       if (request_irq(ite_gpio_irq, ite_gpio_irq_handler, IRQF_SHARED, "gpio", 0) < 0) {
-               misc_deregister(&ite_gpio_miscdev);
-               release_region(ite_gpio_base, 0x1c);
-               return 0;
-       }
-
-       printk("GPIO at 0x%x (irq = %d)\n", ite_gpio_base, ite_gpio_irq);
-
-       return 0;
-}      
-
-static void __exit ite_gpio_exit(void)
-{
-       misc_deregister(&ite_gpio_miscdev);
-}
-
-module_init(ite_gpio_init);
-module_exit(ite_gpio_exit);
-
-MODULE_LICENSE("GPL");
index 3e90aac3751032b74178a85fd31f5778f3bb7d29..e2011669c7bb4bc187a3e216e21a37b1711b9f4e 100644 (file)
@@ -108,7 +108,11 @@ const int NR_TYPES = ARRAY_SIZE(max_vals);
 struct kbd_struct kbd_table[MAX_NR_CONSOLES];
 static struct kbd_struct *kbd = kbd_table;
 
-int spawnpid, spawnsig;
+struct vt_spawn_console vt_spawn_con = {
+       .lock = SPIN_LOCK_UNLOCKED,
+       .pid  = NULL,
+       .sig  = 0,
+};
 
 /*
  * Variables exported for vt.c
@@ -578,9 +582,13 @@ static void fn_compose(struct vc_data *vc, struct pt_regs *regs)
 
 static void fn_spawn_con(struct vc_data *vc, struct pt_regs *regs)
 {
-       if (spawnpid)
-               if (kill_proc(spawnpid, spawnsig, 1))
-                       spawnpid = 0;
+       spin_lock(&vt_spawn_con.lock);
+       if (vt_spawn_con.pid)
+               if (kill_pid(vt_spawn_con.pid, vt_spawn_con.sig, 1)) {
+                       put_pid(vt_spawn_con.pid);
+                       vt_spawn_con.pid = NULL;
+               }
+       spin_unlock(&vt_spawn_con.lock);
 }
 
 static void fn_SAK(struct vc_data *vc, struct pt_regs *regs)
@@ -1285,7 +1293,7 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type,
  */
 static struct input_handle *kbd_connect(struct input_handler *handler,
                                        struct input_dev *dev,
-                                       struct input_device_id *id)
+                                       const struct input_device_id *id)
 {
        struct input_handle *handle;
        int i;
@@ -1334,7 +1342,7 @@ static void kbd_start(struct input_handle *handle)
        tasklet_enable(&keyboard_tasklet);
 }
 
-static struct input_device_id kbd_ids[] = {
+static const struct input_device_id kbd_ids[] = {
        {
                 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
                 .evbit = { BIT(EV_KEY) },
@@ -1362,6 +1370,7 @@ static struct input_handler kbd_handler = {
 int __init kbd_init(void)
 {
        int i;
+       int error;
 
         for (i = 0; i < MAX_NR_CONSOLES; i++) {
                kbd_table[i].ledflagstate = KBD_DEFLEDS;
@@ -1373,7 +1382,9 @@ int __init kbd_init(void)
                kbd_table[i].kbdmode = VC_XLATE;
        }
 
-       input_register_handler(&kbd_handler);
+       error = input_register_handler(&kbd_handler);
+       if (error)
+               return error;
 
        tasklet_enable(&keyboard_tasklet);
        tasklet_schedule(&keyboard_tasklet);
index c1a6d3c48da155da8c9e974090ad6e4efe3a4b8c..b401383808c26ac4c16ce38f15fc129b4dafd56a 100644 (file)
@@ -281,7 +281,7 @@ static int moxa_get_serial_info(struct moxa_str *, struct serial_struct __user *
 static int moxa_set_serial_info(struct moxa_str *, struct serial_struct __user *);
 static void MoxaSetFifo(int port, int enable);
 
-static struct tty_operations moxa_ops = {
+static const struct tty_operations moxa_ops = {
        .open = moxa_open,
        .close = moxa_close,
        .write = moxa_write,
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 27a653772049ff6b78050c8f2ff86f2e327b7967..8253fca8efd527c3a1d763a2805bffc4c20cb77a 100644 (file)
@@ -453,7 +453,7 @@ static int CheckIsMoxaMust(int io)
 
 /* above is modified by Victor Yu. 08-15-2002 */
 
-static struct tty_operations mxser_ops = {
+static const struct tty_operations mxser_ops = {
        .open = mxser_open,
        .close = mxser_close,
        .write = mxser_write,
index 7c57ebfa8640a578d2840ba00a38cef5388eb761..ea1aa7764f8e1a0b756b8be75172488bdc7bf714 100644 (file)
@@ -127,9 +127,8 @@ static void button_consume_callbacks (int bpcount)
 static void button_sequence_finished (unsigned long parameters)
 {
 #ifdef CONFIG_NWBUTTON_REBOOT          /* Reboot using button is enabled */
-       if (button_press_count == reboot_count) {
-               kill_proc (1, SIGINT, 1);       /* Ask init to reboot us */
-       }
+       if (button_press_count == reboot_count)
+               kill_cad_pid(SIGINT, 1);        /* Ask init to reboot us */
 #endif /* CONFIG_NWBUTTON_REBOOT */
        button_consume_callbacks (button_press_count);
        bcount = sprintf (button_output_buffer, "%d\n", button_press_count);
index 00f574cbb0d47ca0c69d8b4b0c2ed77be9e24282..d1ecb2c6de98719803479876d3e9ea0d7f185c03 100644 (file)
@@ -57,7 +57,6 @@
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
 #include <linux/init.h>
-#include <asm/serial.h>
 #include <linux/delay.h>
 #include <linux/ioctl.h>
 
@@ -3010,7 +3009,7 @@ static struct pcmcia_driver mgslpc_driver = {
        .resume         = mgslpc_resume,
 };
 
-static struct tty_operations mgslpc_ops = {
+static const struct tty_operations mgslpc_ops = {
        .open = mgslpc_open,
        .close = mgslpc_close,
        .write = mgslpc_write,
index 34dd4c38110e060f6bdfd866d0aa2bdb41994d08..80d3eedd7f96f32997a69fa24f2134b38c8d1f1f 100644 (file)
@@ -224,7 +224,7 @@ static void pty_set_termios(struct tty_struct *tty, struct termios *old_termios)
         tty->termios->c_cflag |= (CS8 | CREAD);
 }
 
-static struct tty_operations pty_ops = {
+static const struct tty_operations pty_ops = {
        .open = pty_open,
        .close = pty_close,
        .write = pty_write,
diff --git a/drivers/char/qtronixmap.c_shipped b/drivers/char/qtronixmap.c_shipped
deleted file mode 100644 (file)
index 1e2b92b..0000000
+++ /dev/null
@@ -1,265 +0,0 @@
-
-/* Do not edit this file! It was automatically generated by   */
-/*    loadkeys --mktable defkeymap.map > defkeymap.c          */
-
-#include <linux/types.h>
-#include <linux/keyboard.h>
-#include <linux/kd.h>
-
-u_short plain_map[NR_KEYS] = {
-       0xf200, 0xf060, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036,
-       0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf200, 0xf07f,
-       0xf009, 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75,
-       0xfb69, 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf05c, 0xf207, 0xfb61,
-       0xfb73, 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c,
-       0xf03b, 0xf027, 0xf060, 0xf201, 0xf700, 0xf200, 0xfb7a, 0xfb78,
-       0xfb63, 0xfb76, 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f,
-       0xf200, 0xf700, 0xf702, 0xf200, 0xf703, 0xf020, 0xf703, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf601,
-       0xf200, 0xf200, 0xf200, 0xf603, 0xf600, 0xf118, 0xf119, 0xf200,
-       0xf200, 0xf602, 0xf208, 0xf02d, 0xf02b, 0xf30c, 0xf02e, 0xf30d,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf117, 0xf600, 0xf200, 0xf01b, 0xf200,
-       0xf100, 0xf101, 0xf102, 0xf103, 0xf104, 0xf105, 0xf106, 0xf107,
-       0xf108, 0xf109, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, 0xf200,
-};
-
-u_short shift_map[NR_KEYS] = {
-       0xf200, 0xf07e, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e,
-       0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf200, 0xf07f,
-       0xf009, 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55,
-       0xfb49, 0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf07c, 0xf207, 0xfb41,
-       0xfb53, 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c,
-       0xf03a, 0xf022, 0xf07e, 0xf201, 0xf700, 0xf200, 0xfb5a, 0xfb58,
-       0xfb43, 0xfb56, 0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f,
-       0xf200, 0xf700, 0xf702, 0xf200, 0xf703, 0xf020, 0xf703, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf601,
-       0xf200, 0xf200, 0xf200, 0xf603, 0xf600, 0xf20b, 0xf20a, 0xf200,
-       0xf200, 0xf602, 0xf213, 0xf02d, 0xf02b, 0xf30c, 0xf02e, 0xf30d,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf117, 0xf600, 0xf200, 0xf01b, 0xf200,
-       0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e, 0xf10f, 0xf110, 0xf111,
-       0xf112, 0xf113, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, 0xf200,
-};
-
-u_short altgr_map[NR_KEYS] = {
-       0xf200, 0xf200, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200,
-       0xf07b, 0xf05b, 0xf05d, 0xf07d, 0xf05c, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75,
-       0xfb69, 0xfb6f, 0xfb70, 0xf200, 0xf200, 0xf200, 0xf207, 0xfb61,
-       0xfb73, 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c,
-       0xf200, 0xf200, 0xf200, 0xf201, 0xf700, 0xf200, 0xfb7a, 0xfb78,
-       0xfb63, 0xfb76, 0xfb62, 0xfb6e, 0xfb6d, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf700, 0xf702, 0xf200, 0xf703, 0xf200, 0xf703, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf601,
-       0xf200, 0xf200, 0xf200, 0xf603, 0xf600, 0xf118, 0xf119, 0xf200,
-       0xf200, 0xf602, 0xf208, 0xf02d, 0xf02b, 0xf30c, 0xf02e, 0xf30d,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf117, 0xf600, 0xf200, 0xf200, 0xf200,
-       0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, 0xf511, 0xf512, 0xf513,
-       0xf514, 0xf515, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, 0xf200,
-};
-
-u_short ctrl_map[NR_KEYS] = {
-       0xf200, 0xf200, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01d, 0xf01e,
-       0xf01f, 0xf07f, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf008,
-       0xf200, 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015,
-       0xf009, 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf01c, 0xf207, 0xf001,
-       0xf013, 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c,
-       0xf007, 0xf000, 0xf200, 0xf201, 0xf700, 0xf200, 0xf01a, 0xf018,
-       0xf003, 0xf016, 0xf002, 0xf00e, 0xf20e, 0xf07f, 0xf200, 0xf200,
-       0xf200, 0xf700, 0xf702, 0xf200, 0xf703, 0xf000, 0xf703, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf601,
-       0xf200, 0xf200, 0xf200, 0xf603, 0xf600, 0xf118, 0xf119, 0xf200,
-       0xf200, 0xf602, 0xf208, 0xf02d, 0xf02b, 0xf30c, 0xf02e, 0xf30d,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf117, 0xf600, 0xf200, 0xf200, 0xf200,
-       0xf100, 0xf101, 0xf102, 0xf103, 0xf104, 0xf105, 0xf106, 0xf107,
-       0xf108, 0xf109, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, 0xf200,
-};
-
-u_short shift_ctrl_map[NR_KEYS] = {
-       0xf200, 0xf200, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015,
-       0xf009, 0xf00f, 0xf010, 0xf200, 0xf200, 0xf200, 0xf207, 0xf001,
-       0xf013, 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c,
-       0xf200, 0xf200, 0xf200, 0xf201, 0xf700, 0xf200, 0xf01a, 0xf018,
-       0xf003, 0xf016, 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf700, 0xf702, 0xf200, 0xf703, 0xf200, 0xf703, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf601,
-       0xf200, 0xf200, 0xf200, 0xf603, 0xf600, 0xf118, 0xf119, 0xf200,
-       0xf200, 0xf602, 0xf208, 0xf02d, 0xf02b, 0xf30c, 0xf02e, 0xf30d,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf117, 0xf600, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, 0xf200,
-};
-
-u_short alt_map[NR_KEYS] = {
-       0xf200, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836,
-       0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf200, 0xf87f,
-       0xf809, 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875,
-       0xf869, 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf85c, 0xf207, 0xf861,
-       0xf873, 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf83b,
-       0xf827, 0xf860, 0xf200, 0xf80d, 0xf700, 0xf200, 0xf87a, 0xf878,
-       0xf863, 0xf876, 0xf862, 0xf82c, 0xf82e, 0xf82f, 0xf200, 0xf200,
-       0xf200, 0xf700, 0xf702, 0xf200, 0xf703, 0xf820, 0xf703, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf210,
-       0xf200, 0xf200, 0xf200, 0xf603, 0xf600, 0xf118, 0xf119, 0xf200,
-       0xf200, 0xf211, 0xf208, 0xf02d, 0xf02b, 0xf30c, 0xf02e, 0xf30d,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf117, 0xf600, 0xf200, 0xf200, 0xf200,
-       0xf500, 0xf501, 0xf502, 0xf503, 0xf504, 0xf505, 0xf506, 0xf507,
-       0xf508, 0xf509, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, 0xf200,
-};
-
-u_short ctrl_alt_map[NR_KEYS] = {
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815,
-       0xf809, 0xf80f, 0xf810, 0xf200, 0xf200, 0xf200, 0xf207, 0xf801,
-       0xf813, 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c,
-       0xf200, 0xf200, 0xf200, 0xf201, 0xf700, 0xf200, 0xf81a, 0xf818,
-       0xf803, 0xf816, 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf700, 0xf702, 0xf200, 0xf703, 0xf200, 0xf703, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf601,
-       0xf200, 0xf200, 0xf200, 0xf603, 0xf600, 0xf118, 0xf119, 0xf200,
-       0xf200, 0xf602, 0xf208, 0xf02d, 0xf02b, 0xf30c, 0xf02e, 0xf30d,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf117, 0xf600, 0xf200, 0xf200, 0xf200,
-       0xf500, 0xf501, 0xf502, 0xf503, 0xf504, 0xf505, 0xf506, 0xf507,
-       0xf508, 0xf509, 0xf200, 0xf200, 0xf200, 0xf200, 0xf11d, 0xf200,
-};
-
-ushort *key_maps[MAX_NR_KEYMAPS] = {
-       plain_map, shift_map, altgr_map, 0,
-       ctrl_map, shift_ctrl_map, 0, 0,
-       alt_map, 0, 0, 0,
-       ctrl_alt_map,   0
-};
-
-unsigned int keymap_count = 7;
-
-
-/*
- * Philosophy: most people do not define more strings, but they who do
- * often want quite a lot of string space. So, we statically allocate
- * the default and allocate dynamically in chunks of 512 bytes.
- */
-
-char func_buf[] = {
-       '\033', '[', '[', 'A', 0, 
-       '\033', '[', '[', 'B', 0, 
-       '\033', '[', '[', 'C', 0, 
-       '\033', '[', '[', 'D', 0, 
-       '\033', '[', '[', 'E', 0, 
-       '\033', '[', '1', '7', '~', 0, 
-       '\033', '[', '1', '8', '~', 0, 
-       '\033', '[', '1', '9', '~', 0, 
-       '\033', '[', '2', '0', '~', 0, 
-       '\033', '[', '2', '1', '~', 0, 
-       '\033', '[', '2', '3', '~', 0, 
-       '\033', '[', '2', '4', '~', 0, 
-       '\033', '[', '2', '5', '~', 0, 
-       '\033', '[', '2', '6', '~', 0, 
-       '\033', '[', '2', '8', '~', 0, 
-       '\033', '[', '2', '9', '~', 0, 
-       '\033', '[', '3', '1', '~', 0, 
-       '\033', '[', '3', '2', '~', 0, 
-       '\033', '[', '3', '3', '~', 0, 
-       '\033', '[', '3', '4', '~', 0, 
-       '\033', '[', '1', '~', 0, 
-       '\033', '[', '2', '~', 0, 
-       '\033', '[', '3', '~', 0, 
-       '\033', '[', '4', '~', 0, 
-       '\033', '[', '5', '~', 0, 
-       '\033', '[', '6', '~', 0, 
-       '\033', '[', 'M', 0, 
-       '\033', '[', 'P', 0, 
-};
-
-
-char *funcbufptr = func_buf;
-int funcbufsize = sizeof(func_buf);
-int funcbufleft = 0;          /* space left */
-
-char *func_table[MAX_NR_FUNC] = {
-       func_buf + 0,
-       func_buf + 5,
-       func_buf + 10,
-       func_buf + 15,
-       func_buf + 20,
-       func_buf + 25,
-       func_buf + 31,
-       func_buf + 37,
-       func_buf + 43,
-       func_buf + 49,
-       func_buf + 55,
-       func_buf + 61,
-       func_buf + 67,
-       func_buf + 73,
-       func_buf + 79,
-       func_buf + 85,
-       func_buf + 91,
-       func_buf + 97,
-       func_buf + 103,
-       func_buf + 109,
-       func_buf + 115,
-       func_buf + 120,
-       func_buf + 125,
-       func_buf + 130,
-       func_buf + 135,
-       func_buf + 140,
-       func_buf + 145,
-       0,
-       0,
-       func_buf + 149,
-       0,
-};
-
-struct kbdiacr accent_table[MAX_DIACR] = {
-       {'`', 'A', 'À'},        {'`', 'a', 'à'},
-       {'\'', 'A', 'Á'},       {'\'', 'a', 'á'},
-       {'^', 'A', 'Â'},        {'^', 'a', 'â'},
-       {'~', 'A', 'Ã'},        {'~', 'a', 'ã'},
-       {'"', 'A', 'Ä'},        {'"', 'a', 'ä'},
-       {'O', 'A', 'Å'},        {'o', 'a', 'å'},
-       {'0', 'A', 'Å'},        {'0', 'a', 'å'},
-       {'A', 'A', 'Å'},        {'a', 'a', 'å'},
-       {'A', 'E', 'Æ'},        {'a', 'e', 'æ'},
-       {',', 'C', 'Ç'},        {',', 'c', 'ç'},
-       {'`', 'E', 'È'},        {'`', 'e', 'è'},
-       {'\'', 'E', 'É'},       {'\'', 'e', 'é'},
-       {'^', 'E', 'Ê'},        {'^', 'e', 'ê'},
-       {'"', 'E', 'Ë'},        {'"', 'e', 'ë'},
-       {'`', 'I', 'Ì'},        {'`', 'i', 'ì'},
-       {'\'', 'I', 'Í'},       {'\'', 'i', 'í'},
-       {'^', 'I', 'Î'},        {'^', 'i', 'î'},
-       {'"', 'I', 'Ï'},        {'"', 'i', 'ï'},
-       {'-', 'D', 'Ð'},        {'-', 'd', 'ð'},
-       {'~', 'N', 'Ñ'},        {'~', 'n', 'ñ'},
-       {'`', 'O', 'Ò'},        {'`', 'o', 'ò'},
-       {'\'', 'O', 'Ó'},       {'\'', 'o', 'ó'},
-       {'^', 'O', 'Ô'},        {'^', 'o', 'ô'},
-       {'~', 'O', 'Õ'},        {'~', 'o', 'õ'},
-       {'"', 'O', 'Ö'},        {'"', 'o', 'ö'},
-       {'/', 'O', 'Ø'},        {'/', 'o', 'ø'},
-       {'`', 'U', 'Ù'},        {'`', 'u', 'ù'},
-       {'\'', 'U', 'Ú'},       {'\'', 'u', 'ú'},
-       {'^', 'U', 'Û'},        {'^', 'u', 'û'},
-       {'"', 'U', 'Ü'},        {'"', 'u', 'ü'},
-       {'\'', 'Y', 'Ý'},       {'\'', 'y', 'ý'},
-       {'T', 'H', 'Þ'},        {'t', 'h', 'þ'},
-       {'s', 's', 'ß'},        {'"', 'y', 'ÿ'},
-       {'s', 'z', 'ß'},        {'i', 'j', 'ÿ'},
-};
-
-unsigned int accent_table_size = 68;
diff --git a/drivers/char/qtronixmap.map b/drivers/char/qtronixmap.map
deleted file mode 100644 (file)
index 8d1ff5c..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-# Default kernel keymap. This uses 7 modifier combinations.
-keymaps 0-2,4-5,8,12
-# Change the above line into
-#      keymaps 0-2,4-6,8,12
-# in case you want the entries
-#      altgr   control keycode  83 = Boot            
-#      altgr   control keycode 111 = Boot            
-# below.
-#
-# In fact AltGr is used very little, and one more keymap can
-# be saved by mapping AltGr to Alt (and adapting a few entries):
-# keycode 100 = Alt
-#
-keycode   1 = grave        asciitilde
-       alt     keycode   1 = Meta_Escape     
-keycode   2 = one              exclam          
-       alt     keycode   2 = Meta_one        
-keycode   3 = two              at               at              
-       control keycode   3 = nul             
-       shift   control keycode   3 = nul             
-       alt     keycode   3 = Meta_two        
-keycode   4 = three            numbersign      
-       control keycode   4 = Escape          
-       alt     keycode   4 = Meta_three      
-keycode   5 = four             dollar           dollar          
-       control keycode   5 = Control_backslash
-       alt     keycode   5 = Meta_four       
-keycode   6 = five             percent         
-       control keycode   6 = Control_bracketright
-       alt     keycode   6 = Meta_five       
-keycode   7 = six              asciicircum     
-       control keycode   7 = Control_asciicircum
-       alt     keycode   7 = Meta_six        
-keycode   8 = seven            ampersand        braceleft       
-       control keycode   8 = Control_underscore
-       alt     keycode   8 = Meta_seven      
-keycode   9 = eight            asterisk         bracketleft     
-       control keycode   9 = Delete          
-       alt     keycode   9 = Meta_eight      
-keycode  10 = nine             parenleft        bracketright    
-       alt     keycode  10 = Meta_nine       
-keycode  11 = zero             parenright       braceright      
-       alt     keycode  11 = Meta_zero       
-keycode  12 = minus            underscore       backslash       
-       control keycode  12 = Control_underscore
-       shift   control keycode  12 = Control_underscore
-       alt     keycode  12 = Meta_minus      
-keycode  13 = equal            plus            
-       alt     keycode  13 = Meta_equal      
-keycode  15 = Delete           Delete          
-       control keycode  15 = BackSpace
-       alt     keycode  15 = Meta_Delete     
-keycode  16 = Tab              Tab             
-       alt     keycode  16 = Meta_Tab        
-keycode  17 = q               
-keycode  18 = w               
-keycode  19 = e
-keycode  20 = r               
-keycode  21 = t               
-keycode  22 = y               
-keycode  23 = u         
-keycode  24 = i               
-keycode  25 = o               
-keycode  26 = p               
-keycode  27 = bracketleft      braceleft       
-       control keycode  27 = Escape          
-       alt     keycode  27 = Meta_bracketleft
-keycode  28 = bracketright     braceright
-       control keycode  28 = Control_bracketright
-       alt     keycode  28 = Meta_bracketright
-keycode  29 = backslash        bar             
-       control keycode  29 = Control_backslash
-       alt     keycode  29 = Meta_backslash  
-keycode  30 = Caps_Lock
-keycode  31 = a               
-keycode  32 = s
-keycode  33 = d
-keycode  34 = f               
-keycode  35 = g               
-keycode  36 = h               
-keycode  37 = j               
-keycode  38 = k               
-keycode  39 = l               
-keycode  40 = semicolon        colon           
-       alt     keycode  39 = Meta_semicolon  
-keycode  41 = apostrophe       quotedbl        
-       control keycode  40 = Control_g       
-       alt     keycode  40 = Meta_apostrophe 
-keycode  42 = grave            asciitilde      
-       control keycode  41 = nul             
-       alt     keycode  41 = Meta_grave      
-keycode  43 = Return          
-       alt     keycode  43 = Meta_Control_m  
-keycode  44 = Shift               
-keycode  46 = z
-keycode  47 = x               
-keycode  48 = c
-keycode  49 = v               
-keycode  50 = b               
-keycode  51 = n
-keycode  52 = m
-keycode  53 = comma            less            
-       alt     keycode  51 = Meta_comma      
-keycode  54 = period           greater         
-       control keycode  52 = Compose         
-       alt     keycode  52 = Meta_period     
-keycode  55 = slash            question        
-       control keycode  53 = Delete          
-       alt     keycode  53 = Meta_slash      
-keycode  57 = Shift
-keycode  58 = Control
-keycode  60 = Alt
-keycode  61 = space            space           
-       control keycode  61 = nul             
-       alt     keycode  61 = Meta_space      
-keycode  62 = Alt
-
-keycode 75 = Insert          
-keycode 76 = Delete          
-
-keycode 83 = Up              
-keycode 84 = Down              
-
-keycode 85 = Prior           
-       shift   keycode 85 = Scroll_Backward 
-keycode 86 = Next            
-       shift   keycode 86 = Scroll_Forward  
-keycode 89 = Right           
-       alt     keycode 89 = Incr_Console
-keycode 79 = Left            
-       alt     keycode 79 = Decr_Console
-
-keycode  90 = Num_Lock
-       shift   keycode  90 = Bare_Num_Lock
-
-keycode 91 = minus
-keycode 92 = plus
-keycode 93 = KP_Multiply
-keycode 94 = period
-keycode 95 = KP_Divide
-
-keycode 107 = Select          
-keycode 108 = Down            
-
-keycode 110 = Escape           Escape          
-       alt     keycode   1 = Meta_Escape     
-
-keycode  112 = F1              F11              Console_13      
-       control keycode  112 = F1              
-       alt     keycode  112 = Console_1       
-       control alt     keycode  112 = Console_1       
-keycode  113 = F2              F12              Console_14      
-       control keycode  113 = F2              
-       alt     keycode  113 = Console_2       
-       control alt     keycode  113 = Console_2       
-keycode  114 = F3              F13              Console_15      
-       control keycode  114 = F3              
-       alt     keycode  114 = Console_3       
-       control alt     keycode  114 = Console_3       
-keycode  115 = F4              F14              Console_16      
-       control keycode  115 = F4              
-       alt     keycode  115 = Console_4       
-       control alt     keycode  115 = Console_4       
-keycode  116 = F5              F15              Console_17      
-       control keycode  116 = F5              
-       alt     keycode  116 = Console_5       
-       control alt     keycode  116 = Console_5       
-keycode  117 = F6              F16              Console_18      
-       control keycode  117 = F6              
-       alt     keycode  117 = Console_6       
-       control alt     keycode  117 = Console_6       
-keycode  118 = F7              F17              Console_19      
-       control keycode  118 = F7              
-       alt     keycode  118 = Console_7       
-       control alt     keycode  118 = Console_7       
-keycode  119 = F8              F18              Console_20      
-       control keycode  119 = F8              
-       alt     keycode  119 = Console_8       
-       control alt     keycode  119 = Console_8       
-keycode  120 = F9              F19              Console_21      
-       control keycode  120 = F9              
-       alt     keycode  120 = Console_9       
-       control alt     keycode  120 = Console_9       
-keycode  121 = F10             F20              Console_22      
-       control keycode  121 = F10             
-       alt     keycode  121 = Console_10      
-       control alt     keycode  121 = Console_10      
-       
-keycode 126 = Pause           
-
-
-string F1 = "\033[[A"
-string F2 = "\033[[B"
-string F3 = "\033[[C"
-string F4 = "\033[[D"
-string F5 = "\033[[E"
-string F6 = "\033[17~"
-string F7 = "\033[18~"
-string F8 = "\033[19~"
-string F9 = "\033[20~"
-string F10 = "\033[21~"
-string F11 = "\033[23~"
-string F12 = "\033[24~"
-string F13 = "\033[25~"
-string F14 = "\033[26~"
-string F15 = "\033[28~"
-string F16 = "\033[29~"
-string F17 = "\033[31~"
-string F18 = "\033[32~"
-string F19 = "\033[33~"
-string F20 = "\033[34~"
-string Find = "\033[1~"
-string Insert = "\033[2~"
-string Remove = "\033[3~"
-string Select = "\033[4~"
-string Prior = "\033[5~"
-string Next = "\033[6~"
-string Macro = "\033[M"
-string Pause = "\033[P"
-compose '`' 'A' to 'À'
-compose '`' 'a' to 'à'
-compose '\'' 'A' to 'Á'
-compose '\'' 'a' to 'á'
-compose '^' 'A' to 'Â'
-compose '^' 'a' to 'â'
-compose '~' 'A' to 'Ã'
-compose '~' 'a' to 'ã'
-compose '"' 'A' to 'Ä'
-compose '"' 'a' to 'ä'
-compose 'O' 'A' to 'Å'
-compose 'o' 'a' to 'å'
-compose '0' 'A' to 'Å'
-compose '0' 'a' to 'å'
-compose 'A' 'A' to 'Å'
-compose 'a' 'a' to 'å'
-compose 'A' 'E' to 'Æ'
-compose 'a' 'e' to 'æ'
-compose ',' 'C' to 'Ç'
-compose ',' 'c' to 'ç'
-compose '`' 'E' to 'È'
-compose '`' 'e' to 'è'
-compose '\'' 'E' to 'É'
-compose '\'' 'e' to 'é'
-compose '^' 'E' to 'Ê'
-compose '^' 'e' to 'ê'
-compose '"' 'E' to 'Ë'
-compose '"' 'e' to 'ë'
-compose '`' 'I' to 'Ì'
-compose '`' 'i' to 'ì'
-compose '\'' 'I' to 'Í'
-compose '\'' 'i' to 'í'
-compose '^' 'I' to 'Î'
-compose '^' 'i' to 'î'
-compose '"' 'I' to 'Ï'
-compose '"' 'i' to 'ï'
-compose '-' 'D' to 'Ð'
-compose '-' 'd' to 'ð'
-compose '~' 'N' to 'Ñ'
-compose '~' 'n' to 'ñ'
-compose '`' 'O' to 'Ò'
-compose '`' 'o' to 'ò'
-compose '\'' 'O' to 'Ó'
-compose '\'' 'o' to 'ó'
-compose '^' 'O' to 'Ô'
-compose '^' 'o' to 'ô'
-compose '~' 'O' to 'Õ'
-compose '~' 'o' to 'õ'
-compose '"' 'O' to 'Ö'
-compose '"' 'o' to 'ö'
-compose '/' 'O' to 'Ø'
-compose '/' 'o' to 'ø'
-compose '`' 'U' to 'Ù'
-compose '`' 'u' to 'ù'
-compose '\'' 'U' to 'Ú'
-compose '\'' 'u' to 'ú'
-compose '^' 'U' to 'Û'
-compose '^' 'u' to 'û'
-compose '"' 'U' to 'Ü'
-compose '"' 'u' to 'ü'
-compose '\'' 'Y' to 'Ý'
-compose '\'' 'y' to 'ý'
-compose 'T' 'H' to 'Þ'
-compose 't' 'h' to 'þ'
-compose 's' 's' to 'ß'
-compose '"' 'y' to 'ÿ'
-compose 's' 'z' to 'ß'
-compose 'i' 'j' to 'ÿ'
index b430a12eb8190d9266ccd0de322c243021a1086e..07f47a0208a7200b4e0ba1f32bd747d82ae1db6b 100644 (file)
@@ -889,8 +889,8 @@ static void init_std_data(struct entropy_store *r)
 
        do_gettimeofday(&tv);
        add_entropy_words(r, (__u32 *)&tv, sizeof(tv)/4);
-       add_entropy_words(r, (__u32 *)&system_utsname,
-                         sizeof(system_utsname)/4);
+       add_entropy_words(r, (__u32 *)utsname(),
+                         sizeof(*(utsname()))/4);
 }
 
 static int __init rand_initialize(void)
index 3fa80aaf452751b24397192406ee944f7f3e04bc..202a3b0945b78749dbf0c4cc97356e217753f07b 100644 (file)
@@ -727,7 +727,7 @@ static struct vpd_prom *get_VPD_PROM(struct Host *hp)
        return &vpdp;
 }
 
-static struct tty_operations rio_ops = {
+static const struct tty_operations rio_ops = {
        .open = riotopen,
        .close = gs_close,
        .write = gs_write,
index 06b9f78a95d98224d91e0d70a34c6544bcb4a465..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);
@@ -1583,7 +1582,7 @@ static void do_softint(void *private_)
        }
 }
 
-static struct tty_operations riscom_ops = {
+static const struct tty_operations riscom_ops = {
        .open  = rc_open,
        .close = rc_close,
        .write = rc_write,
@@ -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 0ac131881322c96920b049c45e8aa64d5fbdb635..bac80056f7e0c7e45893c7f7a46f9b2c196222af 100644 (file)
@@ -2334,7 +2334,7 @@ static int __init init_ISA(int i)
        return (1);
 }
 
-static struct tty_operations rocket_ops = {
+static const struct tty_operations rocket_ops = {
        .open = rp_open,
        .close = rp_close,
        .write = rp_write,
index 510bd3e0e88b432744ab8064bcaa9edaea95287d..65c751d0d64350b2b6c25df7d777504da53c6c21 100644 (file)
@@ -661,7 +661,7 @@ static void a2232_init_portstructs(void)
        }
 }
 
-static struct tty_operations a2232_ops = {
+static const struct tty_operations a2232_ops = {
        .open = a2232_open,
        .close = gs_close,
        .write = gs_write,
index 21a710cb4bbaed1df2ebfc6a6044bcf5abeb67c4..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
      */
@@ -2158,7 +2140,7 @@ mvme167_serial_console_setup(int cflag)
                                        rcor >> 5, rbpr);
 } /* serial_console_init */
 
-static struct tty_operations cy_ops = {
+static const struct tty_operations cy_ops = {
        .open = cy_open,
        .close = cy_close,
        .write = cy_write,
index d12d4f629cec80ca1137fc4e0fc8ad0351f8bfa2..864854c58866ad12076e970acbea1181872e4a79 100644 (file)
@@ -220,7 +220,7 @@ scdrv_dispatch_event(char *event, int len)
                               " Sending SIGPWR to init...\n");
 
                /* give a SIGPWR signal to init proc */
-               kill_proc(1, SIGPWR, 0);
+               kill_cad_pid(SIGPWR, 0);
        } else {
                /* print to system log */
                printk("%s|$(0x%x)%s\n", severity, esp_code, desc);
index f52c7c31badf0544bd7024aa12d8feaffeeb4699..902c48dca3bc98e86938fb23a0affbd052d921ea 100644 (file)
@@ -2363,7 +2363,7 @@ static void do_softint(void *private_)
        func_exit();
 }
 
-static struct tty_operations sx_ops = {
+static const struct tty_operations sx_ops = {
        .open  = sx_open,
        .close = sx_close,
        .write = sx_write,
index 3beb2203d24be21375175daf23021bbdd8e6daae..bd711537ec4e851791699c377e2540218aaa7ff6 100644 (file)
@@ -2993,7 +2993,7 @@ static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, uns
        return(rc);
 }
 
-static struct tty_operations stl_ops = {
+static const struct tty_operations stl_ops = {
        .open = stl_open,
        .close = stl_close,
        .write = stl_write,
index e1cd2bc4b1e4222e5806dab4389169ffa774900b..57e31e5eaedb7aa998dff3373fc96f180cb45e79 100644 (file)
@@ -2226,7 +2226,7 @@ static int probe_si (struct sx_board *board)
        return 1;
 }
 
-static struct tty_operations sx_ops = {
+static const struct tty_operations sx_ops = {
        .break_ctl = sx_break,
        .open   = sx_open,
        .close = gs_close,
index 78b1b1a2732b3e9216556c3caa2b77354a0457d6..38d94987de8343988faa9ef3ffe0049a61d5be60 100644 (file)
@@ -87,7 +87,6 @@
 
 #include <linux/vmalloc.h>
 #include <linux/init.h>
-#include <asm/serial.h>
 
 #include <linux/delay.h>
 #include <linux/ioctl.h>
@@ -4360,7 +4359,7 @@ static struct mgsl_struct* mgsl_allocate_device(void)
 
 }      /* end of mgsl_allocate_device()*/
 
-static struct tty_operations mgsl_ops = {
+static const struct tty_operations mgsl_ops = {
        .open = mgsl_open,
        .close = mgsl_close,
        .write = mgsl_write,
index 78bc85180c82d692c4201cf6a692f735fe8ad561..bdc7cb248b8f1818db19b0bbb09ae46904f8cd06 100644 (file)
@@ -3441,7 +3441,7 @@ static void __devexit remove_one(struct pci_dev *dev)
 {
 }
 
-static struct tty_operations ops = {
+static const struct tty_operations ops = {
        .open = open,
        .close = close,
        .write = write,
index 66f3754fbbdf443e891b21cdfcf88c799144e6b9..6eb75dcd79613b2f8c454be4331f496004156000 100644 (file)
@@ -3929,7 +3929,7 @@ void device_init(int adapter_num, struct pci_dev *pdev)
        }
 }
 
-static struct tty_operations ops = {
+static const struct tty_operations ops = {
        .open = open,
        .close = close,
        .write = write,
index d30dc09dbbc9df2ffbb5c09e8f3cb32e334a49e2..9df0ca1be0e31a4e25310e58b370c10da4227c78 100644 (file)
@@ -224,14 +224,16 @@ probe_ti_parallel(int minor)
 {
        int i;
        int seq[] = { 0x00, 0x20, 0x10, 0x30 };
+       int data;
 
        for (i = 3; i >= 0; i--) {
                outbyte(3, minor);
                outbyte(i, minor);
                udelay(delay);
+               data = inbyte(minor) & 0x30;
                pr_debug("tipar: Probing -> %i: 0x%02x 0x%02x\n", i,
-                       data & 0x30, seq[i]);
-               if ((inbyte(minor) & 0x30) != seq[i]) {
+                       data, seq[i]);
+               if (data != seq[i]) {
                        outbyte(3, minor);
                        return -1;
                }
index 333741770f1e079f2fbe0df98b69699a4194f924..e90ea39c7c4b1112fd7d7db878b96d8531a0f162 100644 (file)
@@ -3680,7 +3680,8 @@ void put_tty_driver(struct tty_driver *driver)
        kfree(driver);
 }
 
-void tty_set_operations(struct tty_driver *driver, struct tty_operations *op)
+void tty_set_operations(struct tty_driver *driver,
+                       const struct tty_operations *op)
 {
        driver->open = op->open;
        driver->close = op->close;
index f3efeaf2826e901a65fced866aa86b0c9b21bead..a362ee9c92ddb68305cf0d2b6ba2ef2c89932301 100644 (file)
@@ -1047,7 +1047,7 @@ static int send_open(HvLpIndex remoteLp, void *sem)
                        0, 0, 0, 0);
 }
 
-static struct tty_operations serial_ops = {
+static const struct tty_operations serial_ops = {
        .open = viotty_open,
        .close = viotty_close,
        .write = viotty_write,
index bfe5ea948f6a51a4acb6687efe4f45ab05d441ff..c2ca31eb850ba034b9c7e9f27f06c9e15086d422 100644 (file)
@@ -113,7 +113,7 @@ static struct real_driver scc_real_driver = {
 };
 
 
-static struct tty_operations scc_ops = {
+static const struct tty_operations scc_ops = {
        .open   = scc_open,
        .close = gs_close,
        .write = gs_write,
index fb75da940b59c971472812795b3094966b5c8b73..8e4413f6fbaf6145352ffb5e7c9af0530240cc79 100644 (file)
 #define MAX_NR_CON_DRIVER 16
 
 #define CON_DRIVER_FLAG_MODULE 1
-#define CON_DRIVER_FLAG_INIT 2
+#define CON_DRIVER_FLAG_INIT   2
+#define CON_DRIVER_FLAG_ATTR   4
 
 struct con_driver {
        const struct consw *con;
@@ -138,14 +139,6 @@ const struct consw *conswitchp;
 extern void vcs_make_sysfs(struct tty_struct *tty);
 extern void vcs_remove_sysfs(struct tty_struct *tty);
 
-extern void console_map_init(void);
-#ifdef CONFIG_PROM_CONSOLE
-extern void prom_con_init(void);
-#endif
-#ifdef CONFIG_MDA_CONSOLE
-extern int mda_console_init(void);
-#endif
-
 struct vc vc_cons [MAX_NR_CONSOLES];
 
 #ifndef VT_SINGLE_DRIVER
@@ -903,6 +896,7 @@ void vc_deallocate(unsigned int currcons)
        if (vc_cons_allocated(currcons)) {
                struct vc_data *vc = vc_cons[currcons].d;
                vc->vc_sw->con_deinit(vc);
+               put_pid(vc->vt_pid);
                module_put(vc->vc_sw->owner);
                if (vc->vc_kmalloced)
                        kfree(vc->vc_screenbuf);
@@ -2674,7 +2668,7 @@ static int __init con_init(void)
 }
 console_initcall(con_init);
 
-static struct tty_operations con_ops = {
+static const struct tty_operations con_ops = {
        .open = con_open,
        .close = con_close,
        .write = con_write,
@@ -3069,22 +3063,37 @@ static struct class_device_attribute class_device_attrs[] = {
 static int vtconsole_init_class_device(struct con_driver *con)
 {
        int i;
+       int error = 0;
 
+       con->flag |= CON_DRIVER_FLAG_ATTR;
        class_set_devdata(con->class_dev, con);
-       for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
-               class_device_create_file(con->class_dev,
+       for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) {
+               error = class_device_create_file(con->class_dev,
+                                        &class_device_attrs[i]);
+               if (error)
+                       break;
+       }
+
+       if (error) {
+               while (--i >= 0)
+                       class_device_remove_file(con->class_dev,
                                         &class_device_attrs[i]);
+               con->flag &= ~CON_DRIVER_FLAG_ATTR;
+       }
 
-       return 0;
+       return error;
 }
 
 static void vtconsole_deinit_class_device(struct con_driver *con)
 {
        int i;
 
-       for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
-               class_device_remove_file(con->class_dev,
-                                        &class_device_attrs[i]);
+       if (con->flag & CON_DRIVER_FLAG_ATTR) {
+               for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
+                       class_device_remove_file(con->class_dev,
+                                                &class_device_attrs[i]);
+               con->flag &= ~CON_DRIVER_FLAG_ATTR;
+       }
 }
 
 /**
@@ -3183,6 +3192,7 @@ int register_con_driver(const struct consw *csw, int first, int last)
        } else {
                vtconsole_init_class_device(con_driver);
        }
+
 err:
        release_console_sem();
        module_put(owner);
index a53e382cc10747b2e73a9386c67a78f73700582f..ac5d60edbafaadda7d58dd13601fb70e9ac70a82 100644 (file)
@@ -645,13 +645,16 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
         */
        case KDSIGACCEPT:
        {
-               extern int spawnpid, spawnsig;
                if (!perm || !capable(CAP_KILL))
                  return -EPERM;
                if (!valid_signal(arg) || arg < 1 || arg == SIGKILL)
                  return -EINVAL;
-               spawnpid = current->pid;
-               spawnsig = arg;
+
+               spin_lock_irq(&vt_spawn_con.lock);
+               put_pid(vt_spawn_con.pid);
+               vt_spawn_con.pid = get_pid(task_pid(current));
+               vt_spawn_con.sig = arg;
+               spin_unlock_irq(&vt_spawn_con.lock);
                return 0;
        }
 
@@ -669,7 +672,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                vc->vt_mode = tmp;
                /* the frsig is ignored, so we set it to 0 */
                vc->vt_mode.frsig = 0;
-               vc->vt_pid = current->pid;
+               put_pid(xchg(&vc->vt_pid, get_pid(task_pid(current))));
                /* no switch is required -- saw@shade.msu.ru */
                vc->vt_newvt = -1;
                release_console_sem();
@@ -1060,7 +1063,7 @@ void reset_vc(struct vc_data *vc)
        vc->vt_mode.relsig = 0;
        vc->vt_mode.acqsig = 0;
        vc->vt_mode.frsig = 0;
-       vc->vt_pid = -1;
+       put_pid(xchg(&vc->vt_pid, NULL));
        vc->vt_newvt = -1;
        if (!in_interrupt())    /* Via keyboard.c:SAK() - akpm */
                reset_palette(vc);
@@ -1111,7 +1114,7 @@ static void complete_change_console(struct vc_data *vc)
                 * tell us if the process has gone or something else
                 * is awry
                 */
-               if (kill_proc(vc->vt_pid, vc->vt_mode.acqsig, 1) != 0) {
+               if (kill_pid(vc->vt_pid, vc->vt_mode.acqsig, 1) != 0) {
                /*
                 * The controlling process has died, so we revert back to
                 * normal operation. In this case, we'll also change back
@@ -1171,7 +1174,7 @@ void change_console(struct vc_data *new_vc)
                 * tell us if the process has gone or something else
                 * is awry
                 */
-               if (kill_proc(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) {
+               if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) {
                        /*
                         * It worked. Mark the vt to switch to and
                         * return. The process needs to send us a
index 77ab7e020da0a8ee2672a379d79f93aed3235899..89e46d6dfc4ef789af2e5cfe3f89631607f4c345 100644 (file)
@@ -172,6 +172,17 @@ config OMAP_WATCHDOG
          Support for TI OMAP1610/OMAP1710/OMAP2420 watchdog.  Say 'Y' here to
          enable the OMAP1610/OMAP1710 watchdog timer.
 
+config PNX4008_WATCHDOG
+       tristate "PNX4008 Watchdog"
+       depends on WATCHDOG && ARCH_PNX4008
+       help
+         Say Y here if to include support for the watchdog timer
+         in the PNX4008 processor.
+         This driver can be built as a module by choosing M. The module
+         will be called pnx4008_wdt.
+
+         Say N if you are unsure.
+
 # X86 (i386 + ia64 + x86_64) Architecture
 
 config ACQUIRE_WDT
@@ -305,6 +316,27 @@ config I8XX_TCO
          To compile this driver as a module, choose M here: the
          module will be called i8xx_tco.
 
+config ITCO_WDT
+       tristate "Intel TCO Timer/Watchdog (EXPERIMENTAL)"
+       depends on WATCHDOG && (X86 || IA64) && PCI && EXPERIMENTAL
+       ---help---
+         Hardware driver for the intel TCO timer based watchdog devices.
+         These drivers are included in the Intel 82801 I/O Controller
+         Hub family 'from ICH0 up to ICH7) and in the Intel 6300ESB
+         controller hub.
+
+         The TCO (Total Cost of Ownership) timer is a watchdog timer
+         that will reboot the machine after its second expiration. The
+         expiration time can be configured with the "heartbeat" parameter.
+
+         On some motherboards the driver may fail to reset the chipset's
+         NO_REBOOT flag which prevents the watchdog from rebooting the
+         machine. If this is the case you will get a kernel message like
+         "failed to reset NO_REBOOT flag, reboot disabled by hardware".
+
+         To compile this driver as a module, choose M here: the
+         module will be called iTCO_wdt.
+
 config SC1200_WDT
        tristate "National Semiconductor PC87307/PC97307 (ala SC1200) Watchdog"
        depends on WATCHDOG && X86
index 5099f8be8cc51efab2bc38d98dfd2df495833daf..7f70abad465a3b846d2c1b5558c23496b9ea965c 100644 (file)
@@ -33,6 +33,7 @@ obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o
 obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o
 obj-$(CONFIG_MPCORE_WATCHDOG) += mpcore_wdt.o
 obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o
+obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o
 
 # X86 (i386 + ia64 + x86_64) Architecture
 obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
@@ -46,6 +47,7 @@ obj-$(CONFIG_IBMASR) += ibmasr.o
 obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
 obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o
 obj-$(CONFIG_I8XX_TCO) += i8xx_tco.o
+obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o
 obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o
 obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o
 obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o
index c77fe3cf2852a198ff51133c0d79be03918a2960..154d67e591e5c928b6cd59b97a746e994c46b8d8 100644 (file)
@@ -183,7 +183,7 @@ static int acq_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        }
 
        default:
-         return -ENOIOCTLCMD;
+         return -ENOTTY;
        }
 }
 
index 8069be445edc3683f358e644ec7e883d7d4ad40c..9d732769ba0144bd36a720d4362185dc0bb651d1 100644 (file)
@@ -176,7 +176,7 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        }
 
        default:
-         return -ENOIOCTLCMD;
+         return -ENOTTY;
        }
        return 0;
 }
index c5c94e4c94950ba93035e01e4053c9d1cc916a58..01b0d132ee41b3890b58cb3a983b87742bf69dff 100644 (file)
@@ -236,7 +236,7 @@ static int ali_ioctl(struct inode *inode, struct file *file,
                        return put_user(timeout, p);
 
                default:
-                       return -ENOIOCTLCMD;
+                       return -ENOTTY;
        }
 }
 
@@ -330,17 +330,20 @@ static int __init ali_find_watchdog(void)
        u32 wdog;
 
        /* Check for a 1535 series bridge */
-       pdev = pci_find_device(PCI_VENDOR_ID_AL, 0x1535, NULL);
+       pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x1535, NULL);
        if(pdev == NULL)
                return -ENODEV;
+       pci_dev_put(pdev);
 
        /* Check for the a 7101 PMU */
-       pdev = pci_find_device(PCI_VENDOR_ID_AL, 0x7101, NULL);
+       pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x7101, NULL);
        if(pdev == NULL)
                return -ENODEV;
 
-       if(pci_enable_device(pdev))
+       if(pci_enable_device(pdev)) {
+               pci_dev_put(pdev);
                return -EIO;
+       }
 
        ali_pci = pdev;
 
@@ -447,6 +450,7 @@ static void __exit watchdog_exit(void)
        /* Deregister */
        unregister_reboot_notifier(&ali_notifier);
        misc_deregister(&ali_miscdev);
+       pci_dev_put(ali_pci);
 }
 
 module_init(watchdog_init);
index ffd7684f999b3220572dbcf45cbe7a92b4a9b677..5948863b592b7434d57117dadc381a7584c113be 100644 (file)
@@ -277,7 +277,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                case WDIOC_GETTIMEOUT:
                        return put_user(timeout, p);
                default:
-                       return -ENOIOCTLCMD;
+                       return -ENOTTY;
        }
 }
 
@@ -333,6 +333,7 @@ static void __exit alim7101_wdt_unload(void)
        /* Deregister */
        misc_deregister(&wdt_miscdev);
        unregister_reboot_notifier(&wdt_notifier);
+       pci_dev_put(alim7101_pmu);
 }
 
 static int __init alim7101_wdt_init(void)
@@ -342,7 +343,8 @@ static int __init alim7101_wdt_init(void)
        char tmp;
 
        printk(KERN_INFO PFX "Steve Hill <steve@navaho.co.uk>.\n");
-       alim7101_pmu = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,NULL);
+       alim7101_pmu = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,
+               NULL);
        if (!alim7101_pmu) {
                printk(KERN_INFO PFX "ALi M7101 PMU not present - WDT not set\n");
                return -EBUSY;
@@ -351,21 +353,23 @@ static int __init alim7101_wdt_init(void)
        /* Set the WDT in the PMU to 1 second */
        pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, 0x02);
 
-       ali1543_south = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
+       ali1543_south = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
+               NULL);
        if (!ali1543_south) {
                printk(KERN_INFO PFX "ALi 1543 South-Bridge not present - WDT not set\n");
-               return -EBUSY;
+               goto err_out;
        }
        pci_read_config_byte(ali1543_south, 0x5e, &tmp);
+       pci_dev_put(ali1543_south);
        if ((tmp & 0x1e) == 0x00) {
                if (!use_gpio) {
                        printk(KERN_INFO PFX "Detected old alim7101 revision 'a1d'.  If this is a cobalt board, set the 'use_gpio' module parameter.\n");
-                       return -EBUSY;
+                       goto err_out;
                } 
                nowayout = 1;
        } else if ((tmp & 0x1e) != 0x12 && (tmp & 0x1e) != 0x00) {
                printk(KERN_INFO PFX "ALi 1543 South-Bridge does not have the correct revision number (???1001?) - WDT not set\n");
-               return -EBUSY;
+               goto err_out;
        }
 
        if(timeout < 1 || timeout > 3600) /* arbitrary upper limit */
@@ -404,6 +408,7 @@ static int __init alim7101_wdt_init(void)
 err_out_miscdev:
        misc_deregister(&wdt_miscdev);
 err_out:
+       pci_dev_put(alim7101_pmu);
        return rc;
 }
 
index cc266715ea320b029496d0b5ad1d3ece4dc0d77e..4e7a1145e78fd472a70f9442e3a0c7bec461741d 100644 (file)
@@ -168,7 +168,7 @@ static int at91_wdt_ioctl(struct inode *inode, struct file *file,
                        return 0;
 
                default:
-                       return -ENOIOCTLCMD;
+                       return -ENOTTY;
        }
 }
 
index e3cefc538b40476b341aeed5e4f61a874b64baa4..488902231cc237ec24cd76568af57c186bc6d12d 100644 (file)
@@ -125,7 +125,7 @@ static int booke_wdt_ioctl (struct inode *inode, struct file *file,
                        return -EINVAL;
                return 0;
        default:
-               return -ENOIOCTLCMD;
+               return -ENOTTY;
        }
 
        return 0;
index 04c7e49918db0b5d491521f63a2415d318f0443a..00bdabb90f27b958a76ab7b8d39c4b505892411e 100644 (file)
@@ -183,7 +183,7 @@ static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cm
                        }
                        break;
                default:
-                       return -ENOIOCTLCMD;
+                       return -ENOTTY;
        }
        return 0;
 }
index 77c8a955ae9e1f10f2e548b6b395bffe420d1f48..01cf123b1616db2eebda898dafbd167e994d8099 100644 (file)
@@ -144,7 +144,7 @@ static int
 ep93xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                 unsigned long arg)
 {
-       int ret = -ENOIOCTLCMD;
+       int ret = -ENOTTY;
 
        switch (cmd) {
        case WDIOC_GETSUPPORT:
index 62dbccb2f6df979b23e0129871b6884df40b0c76..4f4269754c462fb21aa2573a23a1028323af98db 100644 (file)
@@ -240,7 +240,7 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file,
 
        switch(cmd) {
        default:
-               return -ENOIOCTLCMD;
+               return -ENOTTY;
 
        case WDIOC_GETSUPPORT:
                return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
index 870539eabbf3a93100693f19f966b1e404104ce5..fb64df4d7c8720107f16e360047c93ef2deac0b4 100644 (file)
@@ -315,7 +315,7 @@ static int esb_ioctl (struct inode *inode, struct file *file,
                         return put_user(heartbeat, p);
 
                 default:
-                        return -ENOIOCTLCMD;
+                        return -ENOTTY;
         }
 }
 
index 8385dd36eefe0fd7074306d7eacec6b4d4b25826..e0627d79707b27f6b91d8ccb47506a29f1fad451 100644 (file)
@@ -356,7 +356,7 @@ static int i8xx_tco_ioctl (struct inode *inode, struct file *file,
                }
 
                default:
-                       return -ENOIOCTLCMD;
+                       return -ENOTTY;
        }
 }
 
@@ -406,18 +406,18 @@ static struct notifier_block i8xx_tco_notifier = {
  * want to register another driver on the same PCI id.
  */
 static struct pci_device_id i8xx_tco_pci_tbl[] = {
-       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0,   PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0,   PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0,   PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10,  PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,   PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12,  PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,   PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12,  PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_0,    PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0,   PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1,       PCI_ANY_ID, PCI_ANY_ID, },
-       { 0, },                 /* End of list */
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_0) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1) },
+       { },                    /* End of list */
 };
 MODULE_DEVICE_TABLE (pci, i8xx_tco_pci_tbl);
 
@@ -434,12 +434,11 @@ static unsigned char __init i8xx_tco_getdevice (void)
         *      Find the PCI device
         */
 
-       while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+       for_each_pci_dev(dev)
                if (pci_match_id(i8xx_tco_pci_tbl, dev)) {
                        i8xx_tco_pci = dev;
                        break;
                }
-       }
 
        if (i8xx_tco_pci) {
                /*
@@ -454,6 +453,7 @@ static unsigned char __init i8xx_tco_getdevice (void)
                /* Something's wrong here, ACPIBASE has to be set */
                if (badr == 0x0001 || badr == 0x0000) {
                        printk (KERN_ERR PFX "failed to get TCOBASE address\n");
+                       pci_dev_put(i8xx_tco_pci);
                        return 0;
                }
 
@@ -465,6 +465,7 @@ static unsigned char __init i8xx_tco_getdevice (void)
                        pci_read_config_byte (i8xx_tco_pci, 0xd4, &val1);
                        if (val1 & 0x02) {
                                printk (KERN_ERR PFX "failed to reset NO_REBOOT flag, reboot disabled by hardware\n");
+                               pci_dev_put(i8xx_tco_pci);
                                return 0;       /* Cannot reset NO_REBOOT bit */
                        }
                }
@@ -476,6 +477,7 @@ static unsigned char __init i8xx_tco_getdevice (void)
                if (!request_region (SMI_EN + 1, 1, "i8xx TCO")) {
                        printk (KERN_ERR PFX "I/O address 0x%04x already in use\n",
                                SMI_EN + 1);
+                       pci_dev_put(i8xx_tco_pci);
                        return 0;
                }
                val1 = inb (SMI_EN + 1);
@@ -542,6 +544,7 @@ unreg_notifier:
 unreg_region:
        release_region (TCOBASE, 0x10);
 out:
+       pci_dev_put(i8xx_tco_pci);
        return ret;
 }
 
@@ -555,6 +558,8 @@ static void __exit watchdog_cleanup (void)
        misc_deregister (&i8xx_tco_miscdev);
        unregister_reboot_notifier(&i8xx_tco_notifier);
        release_region (TCOBASE, 0x10);
+
+       pci_dev_put(i8xx_tco_pci);
 }
 
 module_init(watchdog_init);
diff --git a/drivers/char/watchdog/iTCO_wdt.c b/drivers/char/watchdog/iTCO_wdt.c
new file mode 100644 (file)
index 0000000..8f89948
--- /dev/null
@@ -0,0 +1,735 @@
+/*
+ *     intel TCO Watchdog Driver (Used in i82801 and i6300ESB chipsets)
+ *
+ *     (c) Copyright 2006 Wim Van Sebroeck <wim@iguana.be>.
+ *
+ *     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.
+ *
+ *     Neither Wim Van Sebroeck nor Iguana vzw. admit liability nor
+ *     provide warranty for any of this software. This material is
+ *     provided "AS-IS" and at no charge.
+ *
+ *     The TCO watchdog is implemented in the following I/O controller hubs:
+ *     (See the intel documentation on http://developer.intel.com.)
+ *     82801AA  (ICH)       : document number 290655-003, 290677-014,
+ *     82801AB  (ICHO)      : document number 290655-003, 290677-014,
+ *     82801BA  (ICH2)      : document number 290687-002, 298242-027,
+ *     82801BAM (ICH2-M)    : document number 290687-002, 298242-027,
+ *     82801CA  (ICH3-S)    : document number 290733-003, 290739-013,
+ *     82801CAM (ICH3-M)    : document number 290716-001, 290718-007,
+ *     82801DB  (ICH4)      : document number 290744-001, 290745-020,
+ *     82801DBM (ICH4-M)    : document number 252337-001, 252663-005,
+ *     82801E   (C-ICH)     : document number 273599-001, 273645-002,
+ *     82801EB  (ICH5)      : document number 252516-001, 252517-003,
+ *     82801ER  (ICH5R)     : document number 252516-001, 252517-003,
+ *     82801FB  (ICH6)      : document number 301473-002, 301474-007,
+ *     82801FR  (ICH6R)     : document number 301473-002, 301474-007,
+ *     82801FBM (ICH6-M)    : document number 301473-002, 301474-007,
+ *     82801FW  (ICH6W)     : document number 301473-001, 301474-007,
+ *     82801FRW (ICH6RW)    : document number 301473-001, 301474-007,
+ *     82801GB  (ICH7)      : document number 307013-002, 307014-009,
+ *     82801GR  (ICH7R)     : document number 307013-002, 307014-009,
+ *     82801GDH (ICH7DH)    : document number 307013-002, 307014-009,
+ *     82801GBM (ICH7-M)    : document number 307013-002, 307014-009,
+ *     82801GHM (ICH7-M DH) : document number 307013-002, 307014-009,
+ *     6300ESB  (6300ESB)   : document number 300641-003
+ */
+
+/*
+ *     Includes, defines, variables, module parameters, ...
+ */
+
+/* Module and version information */
+#define DRV_NAME        "iTCO_wdt"
+#define DRV_VERSION     "1.00"
+#define DRV_RELDATE     "30-Jul-2006"
+#define PFX            DRV_NAME ": "
+
+/* Includes */
+#include <linux/config.h>              /* For CONFIG_WATCHDOG_NOWAYOUT/... */
+#include <linux/module.h>              /* For module specific items */
+#include <linux/moduleparam.h>         /* For new moduleparam's */
+#include <linux/types.h>               /* For standard types (like size_t) */
+#include <linux/errno.h>               /* For the -ENODEV/... values */
+#include <linux/kernel.h>              /* For printk/panic/... */
+#include <linux/miscdevice.h>          /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */
+#include <linux/watchdog.h>            /* For the watchdog specific items */
+#include <linux/init.h>                        /* For __init/__exit/... */
+#include <linux/fs.h>                  /* For file operations */
+#include <linux/platform_device.h>     /* For platform_driver framework */
+#include <linux/pci.h>                 /* For pci functions */
+#include <linux/ioport.h>              /* For io-port access */
+#include <linux/spinlock.h>            /* For spin_lock/spin_unlock/... */
+
+#include <asm/uaccess.h>               /* For copy_to_user/put_user/... */
+#include <asm/io.h>                    /* For inb/outb/... */
+
+/* TCO related info */
+enum iTCO_chipsets {
+       TCO_ICH = 0,    /* ICH */
+       TCO_ICH0,       /* ICH0 */
+       TCO_ICH2,       /* ICH2 */
+       TCO_ICH2M,      /* ICH2-M */
+       TCO_ICH3,       /* ICH3-S */
+       TCO_ICH3M,      /* ICH3-M */
+       TCO_ICH4,       /* ICH4 */
+       TCO_ICH4M,      /* ICH4-M */
+       TCO_CICH,       /* C-ICH */
+       TCO_ICH5,       /* ICH5 & ICH5R */
+       TCO_6300ESB,    /* 6300ESB */
+       TCO_ICH6,       /* ICH6 & ICH6R */
+       TCO_ICH6M,      /* ICH6-M */
+       TCO_ICH6W,      /* ICH6W & ICH6RW */
+       TCO_ICH7,       /* ICH7 & ICH7R */
+       TCO_ICH7M,      /* ICH7-M */
+       TCO_ICH7MDH,    /* ICH7-M DH */
+};
+
+static struct {
+       char *name;
+       unsigned int iTCO_version;
+} iTCO_chipset_info[] __devinitdata = {
+       {"ICH", 1},
+       {"ICH0", 1},
+       {"ICH2", 1},
+       {"ICH2-M", 1},
+       {"ICH3-S", 1},
+       {"ICH3-M", 1},
+       {"ICH4", 1},
+       {"ICH4-M", 1},
+       {"C-ICH", 1},
+       {"ICH5 or ICH5R", 1},
+       {"6300ESB", 1},
+       {"ICH6 or ICH6R", 2},
+       {"ICH6-M", 2},
+       {"ICH6W or ICH6RW", 2},
+       {"ICH7 or ICH7R", 2},
+       {"ICH7-M", 2},
+       {"ICH7-M DH", 2},
+       {NULL,0}
+};
+
+/*
+ * This data only exists for exporting the supported PCI ids
+ * via MODULE_DEVICE_TABLE.  We do not actually register a
+ * pci_driver, because the I/O Controller Hub has also other
+ * functions that probably will be registered by other drivers.
+ */
+static struct pci_device_id iTCO_wdt_pci_tbl[] = {
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0,   PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH     },
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0,   PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH0    },
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0,   PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH2    },
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH2M   },
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,   PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH3    },
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH3M   },
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,   PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH4    },
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH4M   },
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_0,    PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_CICH    },
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0,   PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH5    },
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1,       PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_6300ESB },
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0,      PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH6    },
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1,      PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH6M   },
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_2,      PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH6W   },
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0,      PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7    },
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1,      PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7M   },
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31,     PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7MDH },
+       { 0, },                 /* End of list */
+};
+MODULE_DEVICE_TABLE (pci, iTCO_wdt_pci_tbl);
+
+/* Address definitions for the TCO */
+#define        TCOBASE         iTCO_wdt_private.ACPIBASE + 0x60        /* TCO base address                */
+#define        SMI_EN          iTCO_wdt_private.ACPIBASE + 0x30        /* SMI Control and Enable Register */
+
+#define TCO_RLD                TCOBASE + 0x00  /* TCO Timer Reload and Current Value */
+#define TCOv1_TMR      TCOBASE + 0x01  /* TCOv1 Timer Initial Value    */
+#define        TCO_DAT_IN      TCOBASE + 0x02  /* TCO Data In Register         */
+#define        TCO_DAT_OUT     TCOBASE + 0x03  /* TCO Data Out Register        */
+#define        TCO1_STS        TCOBASE + 0x04  /* TCO1 Status Register         */
+#define        TCO2_STS        TCOBASE + 0x06  /* TCO2 Status Register         */
+#define TCO1_CNT       TCOBASE + 0x08  /* TCO1 Control Register        */
+#define TCO2_CNT       TCOBASE + 0x0a  /* TCO2 Control Register        */
+#define TCOv2_TMR      TCOBASE + 0x12  /* TCOv2 Timer Initial Value    */
+
+/* internal variables */
+static unsigned long is_active;
+static char expect_release;
+static struct {                                /* this is private data for the iTCO_wdt device */
+       unsigned int iTCO_version;      /* TCO version/generation */
+       unsigned long ACPIBASE;         /* The cards ACPIBASE address (TCOBASE = ACPIBASE+0x60) */
+       unsigned long __iomem *gcs;     /* NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2) */
+       spinlock_t io_lock;             /* the lock for io operations */
+       struct pci_dev *pdev;           /* the PCI-device */
+} iTCO_wdt_private;
+
+static struct platform_device *iTCO_wdt_platform_device;       /* the watchdog platform device */
+
+/* module parameters */
+#define WATCHDOG_HEARTBEAT 30  /* 30 sec default heartbeat */
+static int heartbeat = WATCHDOG_HEARTBEAT;  /* in seconds */
+module_param(heartbeat, int, 0);
+MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<heartbeat<39 (TCO v1) or 613 (TCO v2), default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+
+/*
+ * Some TCO specific functions
+ */
+
+static inline unsigned int seconds_to_ticks(int seconds)
+{
+       /* the internal timer is stored as ticks which decrement
+        * every 0.6 seconds */
+       return (seconds * 10) / 6;
+}
+
+static void iTCO_wdt_set_NO_REBOOT_bit(void)
+{
+       u32 val32;
+
+       /* Set the NO_REBOOT bit: this disables reboots */
+       if (iTCO_wdt_private.iTCO_version == 2) {
+               val32 = readl(iTCO_wdt_private.gcs);
+               val32 |= 0x00000020;
+               writel(val32, iTCO_wdt_private.gcs);
+       } else if (iTCO_wdt_private.iTCO_version == 1) {
+               pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32);
+               val32 |= 0x00000002;
+               pci_write_config_dword(iTCO_wdt_private.pdev, 0xd4, val32);
+       }
+}
+
+static int iTCO_wdt_unset_NO_REBOOT_bit(void)
+{
+       int ret = 0;
+       u32 val32;
+
+       /* Unset the NO_REBOOT bit: this enables reboots */
+       if (iTCO_wdt_private.iTCO_version == 2) {
+               val32 = readl(iTCO_wdt_private.gcs);
+               val32 &= 0xffffffdf;
+               writel(val32, iTCO_wdt_private.gcs);
+
+               val32 = readl(iTCO_wdt_private.gcs);
+               if (val32 & 0x00000020)
+                       ret = -EIO;
+       } else if (iTCO_wdt_private.iTCO_version == 1) {
+               pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32);
+               val32 &= 0xfffffffd;
+               pci_write_config_dword(iTCO_wdt_private.pdev, 0xd4, val32);
+
+               pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32);
+               if (val32 & 0x00000002)
+                       ret = -EIO;
+       }
+
+       return ret; /* returns: 0 = OK, -EIO = Error */
+}
+
+static int iTCO_wdt_start(void)
+{
+       unsigned int val;
+
+       spin_lock(&iTCO_wdt_private.io_lock);
+
+       /* disable chipset's NO_REBOOT bit */
+       if (iTCO_wdt_unset_NO_REBOOT_bit()) {
+               printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, reboot disabled by hardware\n");
+               return -EIO;
+       }
+
+       /* Bit 11: TCO Timer Halt -> 0 = The TCO timer is enabled to count */
+       val = inw(TCO1_CNT);
+       val &= 0xf7ff;
+       outw(val, TCO1_CNT);
+       val = inw(TCO1_CNT);
+       spin_unlock(&iTCO_wdt_private.io_lock);
+
+       if (val & 0x0800)
+               return -1;
+       return 0;
+}
+
+static int iTCO_wdt_stop(void)
+{
+       unsigned int val;
+
+       spin_lock(&iTCO_wdt_private.io_lock);
+
+       /* Bit 11: TCO Timer Halt -> 1 = The TCO timer is disabled */
+       val = inw(TCO1_CNT);
+       val |= 0x0800;
+       outw(val, TCO1_CNT);
+       val = inw(TCO1_CNT);
+
+       /* Set the NO_REBOOT bit to prevent later reboots, just for sure */
+       iTCO_wdt_set_NO_REBOOT_bit();
+
+       spin_unlock(&iTCO_wdt_private.io_lock);
+
+       if ((val & 0x0800) == 0)
+               return -1;
+       return 0;
+}
+
+static int iTCO_wdt_keepalive(void)
+{
+       spin_lock(&iTCO_wdt_private.io_lock);
+
+       /* Reload the timer by writing to the TCO Timer Counter register */
+       if (iTCO_wdt_private.iTCO_version == 2) {
+               outw(0x01, TCO_RLD);
+       } else if (iTCO_wdt_private.iTCO_version == 1) {
+               outb(0x01, TCO_RLD);
+       }
+
+       spin_unlock(&iTCO_wdt_private.io_lock);
+       return 0;
+}
+
+static int iTCO_wdt_set_heartbeat(int t)
+{
+       unsigned int val16;
+       unsigned char val8;
+       unsigned int tmrval;
+
+       tmrval = seconds_to_ticks(t);
+       /* from the specs: */
+       /* "Values of 0h-3h are ignored and should not be attempted" */
+       if (tmrval < 0x04)
+               return -EINVAL;
+       if (((iTCO_wdt_private.iTCO_version == 2) && (tmrval > 0x3ff)) ||
+           ((iTCO_wdt_private.iTCO_version == 1) && (tmrval > 0x03f)))
+               return -EINVAL;
+
+       /* Write new heartbeat to watchdog */
+       if (iTCO_wdt_private.iTCO_version == 2) {
+               spin_lock(&iTCO_wdt_private.io_lock);
+               val16 = inw(TCOv2_TMR);
+               val16 &= 0xfc00;
+               val16 |= tmrval;
+               outw(val16, TCOv2_TMR);
+               val16 = inw(TCOv2_TMR);
+               spin_unlock(&iTCO_wdt_private.io_lock);
+
+               if ((val16 & 0x3ff) != tmrval)
+                       return -EINVAL;
+       } else if (iTCO_wdt_private.iTCO_version == 1) {
+               spin_lock(&iTCO_wdt_private.io_lock);
+               val8 = inb(TCOv1_TMR);
+               val8 &= 0xc0;
+               val8 |= (tmrval & 0xff);
+               outb(val8, TCOv1_TMR);
+               val8 = inb(TCOv1_TMR);
+               spin_unlock(&iTCO_wdt_private.io_lock);
+
+               if ((val8 & 0x3f) != tmrval)
+                       return -EINVAL;
+       }
+
+       heartbeat = t;
+       return 0;
+}
+
+static int iTCO_wdt_get_timeleft (int *time_left)
+{
+       unsigned int val16;
+       unsigned char val8;
+
+       /* read the TCO Timer */
+       if (iTCO_wdt_private.iTCO_version == 2) {
+               spin_lock(&iTCO_wdt_private.io_lock);
+               val16 = inw(TCO_RLD);
+               val16 &= 0x3ff;
+               spin_unlock(&iTCO_wdt_private.io_lock);
+
+               *time_left = (val16 * 6) / 10;
+       } else if (iTCO_wdt_private.iTCO_version == 1) {
+               spin_lock(&iTCO_wdt_private.io_lock);
+               val8 = inb(TCO_RLD);
+               val8 &= 0x3f;
+               spin_unlock(&iTCO_wdt_private.io_lock);
+
+               *time_left = (val8 * 6) / 10;
+       }
+       return 0;
+}
+
+/*
+ *     /dev/watchdog handling
+ */
+
+static int iTCO_wdt_open (struct inode *inode, struct file *file)
+{
+       /* /dev/watchdog can only be opened once */
+       if (test_and_set_bit(0, &is_active))
+               return -EBUSY;
+
+       /*
+        *      Reload and activate timer
+        */
+       iTCO_wdt_keepalive();
+       iTCO_wdt_start();
+       return nonseekable_open(inode, file);
+}
+
+static int iTCO_wdt_release (struct inode *inode, struct file *file)
+{
+       /*
+        *      Shut off the timer.
+        */
+       if (expect_release == 42) {
+               iTCO_wdt_stop();
+       } else {
+               printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
+               iTCO_wdt_keepalive();
+       }
+       clear_bit(0, &is_active);
+       expect_release = 0;
+       return 0;
+}
+
+static ssize_t iTCO_wdt_write (struct file *file, const char __user *data,
+                             size_t len, loff_t * ppos)
+{
+       /* See if we got the magic character 'V' and reload the timer */
+       if (len) {
+               if (!nowayout) {
+                       size_t i;
+
+                       /* note: just in case someone wrote the magic character
+                        * five months ago... */
+                       expect_release = 0;
+
+                       /* scan to see whether or not we got the magic character */
+                       for (i = 0; i != len; i++) {
+                               char c;
+                               if (get_user(c, data+i))
+                                       return -EFAULT;
+                               if (c == 'V')
+                                       expect_release = 42;
+                       }
+               }
+
+               /* someone wrote to us, we should reload the timer */
+               iTCO_wdt_keepalive();
+       }
+       return len;
+}
+
+static int iTCO_wdt_ioctl (struct inode *inode, struct file *file,
+                         unsigned int cmd, unsigned long arg)
+{
+       int new_options, retval = -EINVAL;
+       int new_heartbeat;
+       int time_left;
+       void __user *argp = (void __user *)arg;
+       int __user *p = argp;
+       static struct watchdog_info ident = {
+               .options =              WDIOF_SETTIMEOUT |
+                                       WDIOF_KEEPALIVEPING |
+                                       WDIOF_MAGICCLOSE,
+               .firmware_version =     0,
+               .identity =             DRV_NAME,
+       };
+
+       switch (cmd) {
+               case WDIOC_GETSUPPORT:
+                       return copy_to_user(argp, &ident,
+                               sizeof (ident)) ? -EFAULT : 0;
+
+               case WDIOC_GETSTATUS:
+               case WDIOC_GETBOOTSTATUS:
+                       return put_user(0, p);
+
+               case WDIOC_KEEPALIVE:
+                       iTCO_wdt_keepalive();
+                       return 0;
+
+               case WDIOC_SETOPTIONS:
+               {
+                       if (get_user(new_options, p))
+                               return -EFAULT;
+
+                       if (new_options & WDIOS_DISABLECARD) {
+                               iTCO_wdt_stop();
+                               retval = 0;
+                       }
+
+                       if (new_options & WDIOS_ENABLECARD) {
+                               iTCO_wdt_keepalive();
+                               iTCO_wdt_start();
+                               retval = 0;
+                       }
+
+                       return retval;
+               }
+
+               case WDIOC_SETTIMEOUT:
+               {
+                       if (get_user(new_heartbeat, p))
+                               return -EFAULT;
+
+                       if (iTCO_wdt_set_heartbeat(new_heartbeat))
+                               return -EINVAL;
+
+                       iTCO_wdt_keepalive();
+                       /* Fall */
+               }
+
+               case WDIOC_GETTIMEOUT:
+                       return put_user(heartbeat, p);
+
+               case WDIOC_GETTIMELEFT:
+               {
+                       if (iTCO_wdt_get_timeleft(&time_left))
+                               return -EINVAL;
+
+                       return put_user(time_left, p);
+               }
+
+               default:
+                       return -ENOTTY;
+       }
+}
+
+/*
+ *     Kernel Interfaces
+ */
+
+static struct file_operations iTCO_wdt_fops = {
+       .owner =        THIS_MODULE,
+       .llseek =       no_llseek,
+       .write =        iTCO_wdt_write,
+       .ioctl =        iTCO_wdt_ioctl,
+       .open =         iTCO_wdt_open,
+       .release =      iTCO_wdt_release,
+};
+
+static struct miscdevice iTCO_wdt_miscdev = {
+       .minor =        WATCHDOG_MINOR,
+       .name =         "watchdog",
+       .fops =         &iTCO_wdt_fops,
+};
+
+/*
+ *     Init & exit routines
+ */
+
+static int iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device_id *ent, struct platform_device *dev)
+{
+       int ret;
+       u32 base_address;
+       unsigned long RCBA;
+       unsigned long val32;
+
+       /*
+        *      Find the ACPI/PM base I/O address which is the base
+        *      for the TCO registers (TCOBASE=ACPIBASE + 0x60)
+        *      ACPIBASE is bits [15:7] from 0x40-0x43
+        */
+       pci_read_config_dword(pdev, 0x40, &base_address);
+       base_address &= 0x00007f80;
+       if (base_address == 0x00000000) {
+               /* Something's wrong here, ACPIBASE has to be set */
+               printk(KERN_ERR PFX "failed to get TCOBASE address\n");
+               pci_dev_put(pdev);
+               return -ENODEV;
+       }
+       iTCO_wdt_private.iTCO_version = iTCO_chipset_info[ent->driver_data].iTCO_version;
+       iTCO_wdt_private.ACPIBASE = base_address;
+       iTCO_wdt_private.pdev = pdev;
+
+       /* Get the Memory-Mapped GCS register, we need it for the NO_REBOOT flag (TCO v2) */
+       /* To get access to it you have to read RCBA from PCI Config space 0xf0
+          and use it as base. GCS = RCBA + ICH6_GCS(0x3410). */
+       if (iTCO_wdt_private.iTCO_version == 2) {
+               pci_read_config_dword(pdev, 0xf0, &base_address);
+               RCBA = base_address & 0xffffc000;
+               iTCO_wdt_private.gcs = ioremap((RCBA + 0x3410),4);
+       }
+
+       /* Check chipset's NO_REBOOT bit */
+       if (iTCO_wdt_unset_NO_REBOOT_bit()) {
+               printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, reboot disabled by hardware\n");
+               ret = -ENODEV;  /* Cannot reset NO_REBOOT bit */
+               goto out;
+       }
+
+       /* Set the NO_REBOOT bit to prevent later reboots, just for sure */
+       iTCO_wdt_set_NO_REBOOT_bit();
+
+       /* Set the TCO_EN bit in SMI_EN register */
+       if (!request_region(SMI_EN, 4, "iTCO_wdt")) {
+               printk(KERN_ERR PFX "I/O address 0x%04lx already in use\n",
+                       SMI_EN );
+               ret = -EIO;
+               goto out;
+       }
+       val32 = inl(SMI_EN);
+       val32 &= 0xffffdfff;    /* Turn off SMI clearing watchdog */
+       outl(val32, SMI_EN);
+       release_region(SMI_EN, 4);
+
+       /* The TCO I/O registers reside in a 32-byte range pointed to by the TCOBASE value */
+       if (!request_region (TCOBASE, 0x20, "iTCO_wdt")) {
+               printk (KERN_ERR PFX "I/O address 0x%04lx already in use\n",
+                       TCOBASE);
+               ret = -EIO;
+               goto out;
+       }
+
+       printk(KERN_INFO PFX "Found a %s TCO device (Version=%d, TCOBASE=0x%04lx)\n",
+               iTCO_chipset_info[ent->driver_data].name,
+               iTCO_chipset_info[ent->driver_data].iTCO_version,
+               TCOBASE);
+
+       /* Clear out the (probably old) status */
+       outb(0, TCO1_STS);
+       outb(3, TCO2_STS);
+
+       /* Make sure the watchdog is not running */
+       iTCO_wdt_stop();
+
+       /* Check that the heartbeat value is within it's range ; if not reset to the default */
+       if (iTCO_wdt_set_heartbeat(heartbeat)) {
+               iTCO_wdt_set_heartbeat(WATCHDOG_HEARTBEAT);
+               printk(KERN_INFO PFX "heartbeat value must be 2<heartbeat<39 (TCO v1) or 613 (TCO v2), using %d\n",
+                       heartbeat);
+       }
+
+       ret = misc_register(&iTCO_wdt_miscdev);
+       if (ret != 0) {
+               printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
+                       WATCHDOG_MINOR, ret);
+               goto unreg_region;
+       }
+
+       printk (KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n",
+               heartbeat, nowayout);
+
+       return 0;
+
+unreg_region:
+       release_region (TCOBASE, 0x20);
+out:
+       if (iTCO_wdt_private.iTCO_version == 2)
+               iounmap(iTCO_wdt_private.gcs);
+       pci_dev_put(iTCO_wdt_private.pdev);
+       iTCO_wdt_private.ACPIBASE = 0;
+       return ret;
+}
+
+static void iTCO_wdt_cleanup(void)
+{
+       /* Stop the timer before we leave */
+       if (!nowayout)
+               iTCO_wdt_stop();
+
+       /* Deregister */
+       misc_deregister(&iTCO_wdt_miscdev);
+       release_region(TCOBASE, 0x20);
+       if (iTCO_wdt_private.iTCO_version == 2)
+               iounmap(iTCO_wdt_private.gcs);
+       pci_dev_put(iTCO_wdt_private.pdev);
+       iTCO_wdt_private.ACPIBASE = 0;
+}
+
+static int iTCO_wdt_probe(struct platform_device *dev)
+{
+       int found = 0;
+       struct pci_dev *pdev = NULL;
+       const struct pci_device_id *ent;
+
+       spin_lock_init(&iTCO_wdt_private.io_lock);
+
+       for_each_pci_dev(pdev) {
+               ent = pci_match_id(iTCO_wdt_pci_tbl, pdev);
+               if (ent) {
+                       if (!(iTCO_wdt_init(pdev, ent, dev))) {
+                               found++;
+                               break;
+                       }
+               }
+       }
+
+       if (!found) {
+               printk(KERN_INFO PFX "No card detected\n");
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+static int iTCO_wdt_remove(struct platform_device *dev)
+{
+       if (iTCO_wdt_private.ACPIBASE)
+               iTCO_wdt_cleanup();
+
+       return 0;
+}
+
+static void iTCO_wdt_shutdown(struct platform_device *dev)
+{
+       iTCO_wdt_stop();
+}
+
+#define iTCO_wdt_suspend NULL
+#define iTCO_wdt_resume  NULL
+
+static struct platform_driver iTCO_wdt_driver = {
+       .probe          = iTCO_wdt_probe,
+       .remove         = iTCO_wdt_remove,
+       .shutdown       = iTCO_wdt_shutdown,
+       .suspend        = iTCO_wdt_suspend,
+       .resume         = iTCO_wdt_resume,
+       .driver         = {
+               .owner  = THIS_MODULE,
+               .name   = DRV_NAME,
+       },
+};
+
+static int __init iTCO_wdt_init_module(void)
+{
+       int err;
+
+       printk(KERN_INFO PFX "Intel TCO WatchDog Timer Driver v%s (%s)\n",
+               DRV_VERSION, DRV_RELDATE);
+
+       err = platform_driver_register(&iTCO_wdt_driver);
+       if (err)
+               return err;
+
+       iTCO_wdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0);
+       if (IS_ERR(iTCO_wdt_platform_device)) {
+               err = PTR_ERR(iTCO_wdt_platform_device);
+               goto unreg_platform_driver;
+       }
+
+       return 0;
+
+unreg_platform_driver:
+       platform_driver_unregister(&iTCO_wdt_driver);
+       return err;
+}
+
+static void __exit iTCO_wdt_cleanup_module(void)
+{
+       platform_device_unregister(iTCO_wdt_platform_device);
+       platform_driver_unregister(&iTCO_wdt_driver);
+       printk(KERN_INFO PFX "Watchdog Module Unloaded.\n");
+}
+
+module_init(iTCO_wdt_init_module);
+module_exit(iTCO_wdt_cleanup_module);
+
+MODULE_AUTHOR("Wim Van Sebroeck <wim@iguana.be>");
+MODULE_DESCRIPTION("Intel TCO WatchDog Timer Driver");
+MODULE_VERSION(DRV_VERSION);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
index fd95f7327798692c8612da2caacd1939ba0b7280..c1ed209a138ca3176313abcf3fa4bdcc2de33b9f 100644 (file)
@@ -199,7 +199,7 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
          break;
 
        default:
-         return -ENOIOCTLCMD;
+         return -ENOTTY;
        }
        return 0;
 }
index 26ceee7a4df0922bd370560a4023d1bfa1892267..dd6760f1a23ba43ecc40342cc9c1d9da3ef13e9c 100644 (file)
@@ -295,7 +295,7 @@ static int asr_ioctl(struct inode *inode, struct file *file,
                }
        }
 
-       return -ENOIOCTLCMD;
+       return -ENOTTY;
 }
 
 static int asr_open(struct inode *inode, struct file *file)
index dacc1c20a310747aa322f9661047d82d47e1c7ab..0bc239308989d53dbf7adf8ad537ada06e086b12 100644 (file)
@@ -112,7 +112,7 @@ static int indydog_ioctl(struct inode *inode, struct file *file,
 
        switch (cmd) {
                default:
-                       return -ENOIOCTLCMD;
+                       return -ENOTTY;
                case WDIOC_GETSUPPORT:
                        if (copy_to_user((struct watchdog_info *)arg,
                                         &ident, sizeof(ident)))
index 692908819e26651cda0aa04ad555a78a651b6a52..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
  *
@@ -107,7 +107,7 @@ static int
 ixp2000_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                        unsigned long arg)
 {
-       int ret = -ENOIOCTLCMD;
+       int ret = -ENOTTY;
        int time;
 
        switch (cmd) {
index 9db5cf2c38c37064334875b42c35c93dbce15126..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
  *
@@ -102,7 +102,7 @@ static int
 ixp4xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                        unsigned long arg)
 {
-       int ret = -ENOIOCTLCMD;
+       int ret = -ENOTTY;
        int time;
 
        switch (cmd) {
index 23734e07fb22503d5395550e49bae577595a1295..276577d08fba2f0f2791c1c1a03de69ad8feb5c2 100644 (file)
@@ -329,7 +329,7 @@ static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                        break;
 
                default:
-                       return -ENOIOCTLCMD;
+                       return -ENOTTY;
        }
 
        return 0;
@@ -426,8 +426,7 @@ static int __init zf_init(void)
        printk(KERN_INFO PFX ": MachZ ZF-Logic Watchdog driver initializing.\n");
 
        ret = zf_get_ZFL_version();
-       printk("%#x\n", ret);
-       if((!ret) || (ret != 0xffff)){
+       if ((!ret) || (ret == 0xffff)) {
                printk(KERN_WARNING PFX ": no ZF-Logic found\n");
                return -ENODEV;
        }
index ae943324d2511e2b5ab174b59d864fc055ca60a3..c2dac0aa1d6254906468a35dcbaea932197b416f 100644 (file)
@@ -185,7 +185,7 @@ static int mixcomwd_ioctl(struct inode *inode, struct file *file,
                        mixcomwd_ping();
                        break;
                default:
-                       return -ENOIOCTLCMD;
+                       return -ENOTTY;
        }
        return 0;
 }
index a480903ee1a59cbf4e17e0bcd150cc0e4aef47c6..18ca752e2f904f7425208c0fd2453ef0c55ebd99 100644 (file)
@@ -125,7 +125,7 @@ static int mpc83xx_wdt_ioctl(struct inode *inode, struct file *file,
        case WDIOC_GETTIMEOUT:
                return put_user(timeout_sec, p);
        default:
-               return -ENOIOCTLCMD;
+               return -ENOTTY;
        }
 }
 
index 35dd9e6e114023e5b9d65a801b23e8a728be1263..8aaed10dd4999e66928168cdb781df1fda97fad2 100644 (file)
@@ -126,7 +126,7 @@ static int mpc8xx_wdt_ioctl(struct inode *inode, struct file *file,
                break;
 
        default:
-               return -ENOIOCTLCMD;
+               return -ENOTTY;
        }
 
        return 0;
index 54b3c56ead0df8abdde728fe425a54ac9fc7661f..02d336ace50477bdb85609329cebb44f6422efdb 100644 (file)
@@ -221,7 +221,7 @@ static int mpcore_wdt_ioctl(struct inode *inode, struct file *file,
        } uarg;
 
        if (_IOC_DIR(cmd) && _IOC_SIZE(cmd) > sizeof(uarg))
-               return -ENOIOCTLCMD;
+               return -ENOTTY;
 
        if (_IOC_DIR(cmd) & _IOC_WRITE) {
                ret = copy_from_user(&uarg, (void __user *)arg, _IOC_SIZE(cmd));
@@ -271,7 +271,7 @@ static int mpcore_wdt_ioctl(struct inode *inode, struct file *file,
                break;
 
        default:
-               return -ENOIOCTLCMD;
+               return -ENOTTY;
        }
 
        if (ret == 0 && _IOC_DIR(cmd) & _IOC_READ) {
index 5c8fab345b403668a6159cc9b8a35392a0cc3b36..b887cdb0133428c07d4f08613b355527dad55b82 100644 (file)
@@ -160,7 +160,7 @@ static int mv64x60_wdt_ioctl(struct inode *inode, struct file *file,
                break;
 
        default:
-               return -ENOIOCTLCMD;
+               return -ENOTTY;
        }
 
        return 0;
index cd7d1b6a5d9fb2dd97aeae7783327f74163d8830..6f8515db5b076028cb620de63e01e8d3692be6f8 100644 (file)
@@ -572,7 +572,7 @@ static int pcwd_ioctl(struct inode *inode, struct file *file,
 
        switch(cmd) {
        default:
-               return -ENOIOCTLCMD;
+               return -ENOTTY;
 
        case WDIOC_GETSUPPORT:
                if(copy_to_user(argp, &ident, sizeof(ident)))
index c7cfd6dbfe1b299b7bcf8db0189645cb3a5fe78d..2de6e497c1402e9fa434c1f7afd12708f1820427 100644 (file)
@@ -541,7 +541,7 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file,
                }
 
                default:
-                       return -ENOIOCTLCMD;
+                       return -ENOTTY;
        }
 }
 
index b7ae73dcdd0823602e1c75983fdb7455f9a7a824..77662cb0ac46e3962beb4f7d660ecaf16fc9bb4c 100644 (file)
@@ -445,7 +445,7 @@ static int usb_pcwd_ioctl(struct inode *inode, struct file *file,
                }
 
                default:
-                       return -ENOIOCTLCMD;
+                       return -ENOTTY;
        }
 }
 
diff --git a/drivers/char/watchdog/pnx4008_wdt.c b/drivers/char/watchdog/pnx4008_wdt.c
new file mode 100644 (file)
index 0000000..db2731b
--- /dev/null
@@ -0,0 +1,362 @@
+/*
+ * drivers/char/watchdog/pnx4008_wdt.c
+ *
+ * Watchdog driver for PNX4008 board
+ *
+ * Authors: Dmitry Chigirev <source@mvista.com>,
+ *         Vitaly Wool <vitalywool@gmail.com>
+ * Based on sa1100 driver,
+ * Copyright (C) 2000 Oleg Drokin <green@crimea.edu>
+ *
+ * 2005-2006 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/init.h>
+#include <linux/bitops.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+
+#include <asm/hardware.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#define MODULE_NAME "PNX4008-WDT: "
+
+/* WatchDog Timer - Chapter 23 Page 207 */
+
+#define DEFAULT_HEARTBEAT 19
+#define MAX_HEARTBEAT     60
+
+/* Watchdog timer register set definition */
+#define WDTIM_INT(p)     ((p) + 0x0)
+#define WDTIM_CTRL(p)    ((p) + 0x4)
+#define WDTIM_COUNTER(p) ((p) + 0x8)
+#define WDTIM_MCTRL(p)   ((p) + 0xC)
+#define WDTIM_MATCH0(p)  ((p) + 0x10)
+#define WDTIM_EMR(p)     ((p) + 0x14)
+#define WDTIM_PULSE(p)   ((p) + 0x18)
+#define WDTIM_RES(p)     ((p) + 0x1C)
+
+/* WDTIM_INT bit definitions */
+#define MATCH_INT      1
+
+/* WDTIM_CTRL bit definitions */
+#define COUNT_ENAB     1
+#define RESET_COUNT    (1<<1)
+#define DEBUG_EN       (1<<2)
+
+/* WDTIM_MCTRL bit definitions */
+#define MR0_INT        1
+#undef  RESET_COUNT0
+#define RESET_COUNT0   (1<<2)
+#define STOP_COUNT0    (1<<2)
+#define M_RES1         (1<<3)
+#define M_RES2         (1<<4)
+#define RESFRC1        (1<<5)
+#define RESFRC2        (1<<6)
+
+/* WDTIM_EMR bit definitions */
+#define EXT_MATCH0      1
+#define MATCH_OUTPUT_HIGH (2<<4)       /*a MATCH_CTRL setting */
+
+/* WDTIM_RES bit definitions */
+#define WDOG_RESET      1      /* read only */
+
+#define WDOG_COUNTER_RATE 13000000     /*the counter clock is 13 MHz fixed */
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+static int heartbeat = DEFAULT_HEARTBEAT;
+
+static spinlock_t io_lock;
+static unsigned long wdt_status;
+#define WDT_IN_USE        0
+#define WDT_OK_TO_CLOSE   1
+#define WDT_REGION_INITED 2
+#define WDT_DEVICE_INITED 3
+
+static unsigned long boot_status;
+
+static struct resource *wdt_mem;
+static void __iomem    *wdt_base;
+struct clk             *wdt_clk;
+
+static void wdt_enable(void)
+{
+       spin_lock(&io_lock);
+
+       if (wdt_clk)
+               clk_set_rate(wdt_clk, 1);
+
+       /* stop counter, initiate counter reset */
+       __raw_writel(RESET_COUNT, WDTIM_CTRL(wdt_base));
+       /*wait for reset to complete. 100% guarantee event */
+       while (__raw_readl(WDTIM_COUNTER(wdt_base)))
+               cpu_relax();
+       /* internal and external reset, stop after that */
+       __raw_writel(M_RES2 | STOP_COUNT0 | RESET_COUNT0,
+               WDTIM_MCTRL(wdt_base));
+       /* configure match output */
+       __raw_writel(MATCH_OUTPUT_HIGH, WDTIM_EMR(wdt_base));
+       /* clear interrupt, just in case */
+       __raw_writel(MATCH_INT, WDTIM_INT(wdt_base));
+       /* the longest pulse period 65541/(13*10^6) seconds ~ 5 ms. */
+       __raw_writel(0xFFFF, WDTIM_PULSE(wdt_base));
+       __raw_writel(heartbeat * WDOG_COUNTER_RATE, WDTIM_MATCH0(wdt_base));
+       /*enable counter, stop when debugger active */
+       __raw_writel(COUNT_ENAB | DEBUG_EN, WDTIM_CTRL(wdt_base));
+
+       spin_unlock(&io_lock);
+}
+
+static void wdt_disable(void)
+{
+       spin_lock(&io_lock);
+
+       __raw_writel(0, WDTIM_CTRL(wdt_base));  /*stop counter */
+       if (wdt_clk)
+               clk_set_rate(wdt_clk, 0);
+
+       spin_unlock(&io_lock);
+}
+
+static int pnx4008_wdt_open(struct inode *inode, struct file *file)
+{
+       if (test_and_set_bit(WDT_IN_USE, &wdt_status))
+               return -EBUSY;
+
+       clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+
+       wdt_enable();
+
+       return nonseekable_open(inode, file);
+}
+
+static ssize_t
+pnx4008_wdt_write(struct file *file, const char *data, size_t len,
+                 loff_t * ppos)
+{
+       /*  Can't seek (pwrite) on this device  */
+       if (ppos != &file->f_pos)
+               return -ESPIPE;
+
+       if (len) {
+               if (!nowayout) {
+                       size_t i;
+
+                       clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+
+                       for (i = 0; i != len; i++) {
+                               char c;
+
+                               if (get_user(c, data + i))
+                                       return -EFAULT;
+                               if (c == 'V')
+                                       set_bit(WDT_OK_TO_CLOSE, &wdt_status);
+                       }
+               }
+               wdt_enable();
+       }
+
+       return len;
+}
+
+static struct watchdog_info ident = {
+       .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE |
+           WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
+       .identity = "PNX4008 Watchdog",
+};
+
+static int
+pnx4008_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+                 unsigned long arg)
+{
+       int ret = -ENOTTY;
+       int time;
+
+       switch (cmd) {
+       case WDIOC_GETSUPPORT:
+               ret = copy_to_user((struct watchdog_info *)arg, &ident,
+                                  sizeof(ident)) ? -EFAULT : 0;
+               break;
+
+       case WDIOC_GETSTATUS:
+               ret = put_user(0, (int *)arg);
+               break;
+
+       case WDIOC_GETBOOTSTATUS:
+               ret = put_user(boot_status, (int *)arg);
+               break;
+
+       case WDIOC_SETTIMEOUT:
+               ret = get_user(time, (int *)arg);
+               if (ret)
+                       break;
+
+               if (time <= 0 || time > MAX_HEARTBEAT) {
+                       ret = -EINVAL;
+                       break;
+               }
+
+               heartbeat = time;
+               wdt_enable();
+               /* Fall through */
+
+       case WDIOC_GETTIMEOUT:
+               ret = put_user(heartbeat, (int *)arg);
+               break;
+
+       case WDIOC_KEEPALIVE:
+               wdt_enable();
+               ret = 0;
+               break;
+       }
+       return ret;
+}
+
+static int pnx4008_wdt_release(struct inode *inode, struct file *file)
+{
+       if (!test_bit(WDT_OK_TO_CLOSE, &wdt_status))
+               printk(KERN_WARNING "WATCHDOG: Device closed unexpectdly\n");
+
+       wdt_disable();
+       clear_bit(WDT_IN_USE, &wdt_status);
+       clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+
+       return 0;
+}
+
+static struct file_operations pnx4008_wdt_fops = {
+       .owner = THIS_MODULE,
+       .llseek = no_llseek,
+       .write = pnx4008_wdt_write,
+       .ioctl = pnx4008_wdt_ioctl,
+       .open = pnx4008_wdt_open,
+       .release = pnx4008_wdt_release,
+};
+
+static struct miscdevice pnx4008_wdt_miscdev = {
+       .minor = WATCHDOG_MINOR,
+       .name = "watchdog",
+       .fops = &pnx4008_wdt_fops,
+};
+
+static int pnx4008_wdt_probe(struct platform_device *pdev)
+{
+       int ret = 0, size;
+       struct resource *res;
+
+       spin_lock_init(&io_lock);
+
+       if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT)
+               heartbeat = DEFAULT_HEARTBEAT;
+
+       printk(KERN_INFO MODULE_NAME
+               "PNX4008 Watchdog Timer: heartbeat %d sec\n", heartbeat);
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (res == NULL) {
+               printk(KERN_INFO MODULE_NAME
+                       "failed to get memory region resouce\n");
+               return -ENOENT;
+       }
+
+       size = res->end - res->start + 1;
+       wdt_mem = request_mem_region(res->start, size, pdev->name);
+
+       if (wdt_mem == NULL) {
+               printk(KERN_INFO MODULE_NAME "failed to get memory region\n");
+               return -ENOENT;
+       }
+       wdt_base = (void __iomem *)IO_ADDRESS(res->start);
+
+       wdt_clk = clk_get(&pdev->dev, "wdt_ck");
+       if (!wdt_clk) {
+               release_resource(wdt_mem);
+               kfree(wdt_mem);
+               goto out;
+       } else
+               clk_set_rate(wdt_clk, 1);
+
+       ret = misc_register(&pnx4008_wdt_miscdev);
+       if (ret < 0) {
+               printk(KERN_ERR MODULE_NAME "cannot register misc device\n");
+               release_resource(wdt_mem);
+               kfree(wdt_mem);
+               clk_set_rate(wdt_clk, 0);
+       } else {
+               boot_status = (__raw_readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ?
+                   WDIOF_CARDRESET : 0;
+               wdt_disable();          /*disable for now */
+               set_bit(WDT_DEVICE_INITED, &wdt_status);
+       }
+
+out:
+       return ret;
+}
+
+static int pnx4008_wdt_remove(struct platform_device *pdev)
+{
+       misc_deregister(&pnx4008_wdt_miscdev);
+       if (wdt_clk) {
+               clk_set_rate(wdt_clk, 0);
+               clk_put(wdt_clk);
+               wdt_clk = NULL;
+       }
+       if (wdt_mem) {
+               release_resource(wdt_mem);
+               kfree(wdt_mem);
+               wdt_mem = NULL;
+       }
+       return 0;
+}
+
+static struct platform_driver platform_wdt_driver = {
+       .driver = {
+               .name = "watchdog",
+       },
+       .probe = pnx4008_wdt_probe,
+       .remove = pnx4008_wdt_remove,
+};
+
+static int __init pnx4008_wdt_init(void)
+{
+       return platform_driver_register(&platform_wdt_driver);
+}
+
+static void __exit pnx4008_wdt_exit(void)
+{
+       return platform_driver_unregister(&platform_wdt_driver);
+}
+
+module_init(pnx4008_wdt_init);
+module_exit(pnx4008_wdt_exit);
+
+MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
+MODULE_DESCRIPTION("PNX4008 Watchdog Driver");
+
+module_param(heartbeat, int, 0);
+MODULE_PARM_DESC(heartbeat,
+                "Watchdog heartbeat period in seconds from 1 to "
+                __MODULE_STRING(MAX_HEARTBEAT) ", default "
+                __MODULE_STRING(DEFAULT_HEARTBEAT));
+
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout,
+                "Set to 1 to keep watchdog running after device release");
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
index be978e8ed754941fa215bc5864e72e8e3bb258ea..b36a04ae9ab8e96306a35ce07680aed56bae40d2 100644 (file)
@@ -62,7 +62,7 @@
 #define CONFIG_S3C2410_WATCHDOG_ATBOOT         (0)
 #define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME   (15)
 
-static int nowayout = WATCHDOG_NOWAYOUT;
+static int nowayout    = WATCHDOG_NOWAYOUT;
 static int tmr_margin  = CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME;
 static int tmr_atboot  = CONFIG_S3C2410_WATCHDOG_ATBOOT;
 static int soft_noboot = 0;
@@ -213,11 +213,10 @@ static int s3c2410wdt_open(struct inode *inode, struct file *file)
        if(down_trylock(&open_lock))
                return -EBUSY;
 
-       if (nowayout) {
+       if (nowayout)
                __module_get(THIS_MODULE);
-       } else {
-               allow_close = CLOSE_STATE_ALLOW;
-       }
+
+       allow_close = CLOSE_STATE_NOT;
 
        /* start the timer */
        s3c2410wdt_start();
@@ -230,6 +229,7 @@ static int s3c2410wdt_release(struct inode *inode, struct file *file)
         *      Shut off the timer.
         *      Lock it in if it's a module and we set nowayout
         */
+
        if (allow_close == CLOSE_STATE_ALLOW) {
                s3c2410wdt_stop();
        } else {
@@ -288,7 +288,7 @@ static int s3c2410wdt_ioctl(struct inode *inode, struct file *file,
 
        switch (cmd) {
                default:
-                       return -ENOIOCTLCMD;
+                       return -ENOTTY;
 
                case WDIOC_GETSUPPORT:
                        return copy_to_user(argp, &s3c2410_wdt_ident,
index 1fc16d995788792794e7cbf3cb673c62314464d0..33c1137f17d6d3e8be5cbbc3abb2bf3099721cc1 100644 (file)
@@ -90,7 +90,7 @@ static struct watchdog_info ident = {
 static int sa1100dog_ioctl(struct inode *inode, struct file *file,
        unsigned int cmd, unsigned long arg)
 {
-       int ret = -ENOIOCTLCMD;
+       int ret = -ENOTTY;
        int time;
        void __user *argp = (void __user *)arg;
        int __user *p = argp;
index 4663c2fd53cd6fbe57f41c6acad6c2577cbc452b..c7b2045bc76b5196f6aa04c732c2dd95a4912704 100644 (file)
@@ -235,7 +235,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        switch(cmd)
        {
                default:
-                       return -ENOIOCTLCMD;
+                       return -ENOTTY;
                case WDIOC_GETSUPPORT:
                        return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
                case WDIOC_GETSTATUS:
index bfc475dabe6d76406dd44b968479227c31678619..8882b427d24f44d988bd2682fee1559a305eecec 100644 (file)
@@ -141,7 +141,7 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file,
 
                return retval;
        default:
-               return -ENOIOCTLCMD;
+               return -ENOTTY;
        }
 }
 
index 7c3cf293a5afc3684111c95bce7ad52653a4cb74..d8d0f28e0acf9ab30b54c9abfd57f12416313e7d 100644 (file)
@@ -180,7 +180,7 @@ static int sc1200wdt_ioctl(struct inode *inode, struct file *file, unsigned int
 
        switch (cmd) {
                default:
-                       return -ENOIOCTLCMD;    /* Keep Pavel Machek amused ;) */
+                       return -ENOTTY;
 
                case WDIOC_GETSUPPORT:
                        if (copy_to_user(argp, &ident, sizeof ident))
index 2c7c9db71be81e9eb5318cebe94d7fd215ecd8c3..caec37ba750a6810e7ea54abb6f73a6e72ef8e69 100644 (file)
@@ -290,7 +290,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        switch(cmd)
        {
                default:
-                       return -ENOIOCTLCMD;
+                       return -ENOTTY;
                case WDIOC_GETSUPPORT:
                        return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
                case WDIOC_GETSTATUS:
index c561299a5537b483ab242399114bb9580c499930..fc0e0347f9d24b665711e21ca8d315567ea20e98 100644 (file)
@@ -166,7 +166,7 @@ static int scx200_wdt_ioctl(struct inode *inode, struct file *file,
 
        switch (cmd) {
        default:
-               return -ENOIOCTLCMD;
+               return -ENOTTY;
        case WDIOC_GETSUPPORT:
                if(copy_to_user(argp, &ident, sizeof(ident)))
                        return -EFAULT;
index e5b8c64f1d65acf4ac67dfb8f77d5376d2ac974e..dc403629aeb3d79a4e112798fe4ababfd2751070 100644 (file)
@@ -360,7 +360,7 @@ static int sh_wdt_ioctl(struct inode *inode, struct file *file,
 
                        return retval;
                default:
-                       return -ENOIOCTLCMD;
+                       return -ENOTTY;
        }
 
        return 0;
index ef8da517545add27cabc43338cbf17d851170625..4067e1f8a36878c7fa6665175051231b2710542f 100644 (file)
@@ -203,7 +203,7 @@ static int softdog_ioctl(struct inode *inode, struct file *file,
        };
        switch (cmd) {
                default:
-                       return -ENOIOCTLCMD;
+                       return -ENOTTY;
                case WDIOC_GETSUPPORT:
                        return copy_to_user(argp, &ident,
                                sizeof(ident)) ? -EFAULT : 0;
index 13f16d41c2fd33a1db8d68cd6b74b41038c2a103..b4adc527e687e8c7e43f047be489b0fbc13f0ddf 100644 (file)
@@ -223,7 +223,7 @@ wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        }
 
        default:
-         return -ENOIOCTLCMD;
+         return -ENOTTY;
        }
        return 0;
 }
index ccf6c0915945d8f517f124cbf989016f6c1b1ddf..b0e5f84d6bafdc24fb9c21742f35b3b0bcdcc965 100644 (file)
@@ -252,7 +252,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        switch(cmd)
        {
                default:
-                       return -ENOIOCTLCMD;
+                       return -ENOTTY;
                case WDIOC_GETSUPPORT:
                        return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
                case WDIOC_GETSTATUS:
index 98f4e17db70a478441bfa9d68e2d1d1a704df12a..2c8d5d8bd4e85303750274d1e9b2907b66c0bdad 100644 (file)
@@ -393,7 +393,7 @@ static int wdt_ioctl(struct inode *inode, struct file *file,
        switch(cmd)
        {
        default:
-               return -ENOIOCTLCMD;
+               return -ENOTTY;
 
        case WDIOC_GETSUPPORT:
                return copy_to_user(uarg.ident, &ident, sizeof(ident)) ? -EFAULT : 0;
index 2bb6a9d6ad2805dba0bb60093a31acf6d5fd7e1c..163e028ef9ed6cee052ee4aa643d8659e17e5bc8 100644 (file)
@@ -174,7 +174,7 @@ static int wafwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd
        }
 
        default:
-               return -ENOIOCTLCMD;
+               return -ENOTTY;
        }
        return 0;
 }
index 5c38cdf41731201b7f37506e79cbadf6cfcd3438..1d64e277567dc487a3ab1f098afe0b38c227d5d4 100644 (file)
@@ -385,7 +385,7 @@ wdrtas_ioctl(struct inode *inode, struct file *file,
                return put_user(wdrtas_interval, argp);
 
        default:
-               return -ENOIOCTLCMD;
+               return -ENOTTY;
        }
 }
 
index 70be81e39a61b3284cd86775ebcdc6fa0d9f54c3..13f23f4a223347393173a86d7c4eb17648f5097a 100644 (file)
@@ -341,7 +341,7 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        switch(cmd)
        {
                default:
-                       return -ENOIOCTLCMD;
+                       return -ENOTTY;
                case WDIOC_GETSUPPORT:
                        return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
 
index 6555fb844f2342113a91ca7cec265403e25f628a..89a249e23fdee2b0377d3e5a04ade645ee7979bf 100644 (file)
@@ -137,7 +137,7 @@ watchdog_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
               unsigned long arg)
 {
        unsigned int new_margin;
-       int ret = -ENOIOCTLCMD;
+       int ret = -ENOTTY;
 
        switch(cmd) {
        case WDIOC_GETSUPPORT:
index a0935bc775f8eb847d39ab4f32eacb8a7914ae47..6253041b235bb2ae0c1260e772f86b659bd799cb 100644 (file)
@@ -361,7 +361,7 @@ static int wdt977_ioctl(struct inode *inode, struct file *file,
        switch(cmd)
        {
        default:
-               return -ENOIOCTLCMD;
+               return -ENOTTY;
 
        case WDIOC_GETSUPPORT:
                return copy_to_user(uarg.ident, &ident,
index 5918ca2c9c35b6c5bbc9bbb2d4012ebab122b80a..74d8cf836e13aa91fb11885dbb5e769ac5f2f49b 100644 (file)
@@ -386,7 +386,7 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd
        switch(cmd)
        {
                default:
-                       return -ENOIOCTLCMD;
+                       return -ENOTTY;
                case WDIOC_GETSUPPORT:
                        return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
 
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 23b086685453d295c6b119c3ce83253cd57e95d7..fc17599c905e001f055cec284d52bd3e1f86a25f 100644 (file)
@@ -227,7 +227,7 @@ static int packetize_data(void *data, size_t length)
        int packet_length;
        u8 *temp;
        u8 *end = (u8 *) data + length;
-       pr_debug("packetize_data: data length %d\n", length);
+       pr_debug("packetize_data: data length %zd\n", length);
        if (!rbu_data.packetsize) {
                printk(KERN_WARNING
                        "dell_rbu: packetsize not specified\n");
@@ -249,7 +249,7 @@ static int packetize_data(void *data, size_t length)
                if ((rc = create_packet(temp, packet_length)))
                        return rc;
 
-               pr_debug("%lu:%lu\n", temp, (end - temp));
+               pr_debug("%p:%lu\n", temp, (end - temp));
                temp += packet_length;
        }
 
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 69d627bd537a8cb7ca1095a7915291995c9dfbc6..0c68d0f0d8e513e028784faf5e5ef7c3a524f599 100644 (file)
@@ -56,7 +56,7 @@ if IDE
 
 config IDE_MAX_HWIFS
        int "Max IDE interfaces"
-       depends on ALPHA || SUPERH || IA64
+       depends on ALPHA || SUPERH || IA64 || EMBEDDED
        default 4
        help
          This is the maximum number of IDE hardware interfaces that will
@@ -594,6 +594,12 @@ config BLK_DEV_HPT366
          ide-probe at boot. It is reported to support DVD II drives, by the
          manufacturer.
 
+config BLK_DEV_JMICRON
+       tristate "JMicron JMB36x support"
+       help
+         Basic support for the JMicron ATA controllers. For full support
+         use the libata drivers.
+
 config BLK_DEV_SC1200
        tristate "National SCx200 chipset support"
        help
@@ -608,15 +614,6 @@ config BLK_DEV_PIIX
          the kernel to change PIO, DMA and UDMA speeds and to configure
          the chip to optimum performance.
 
-config BLK_DEV_IT8172
-       bool "IT8172 IDE support"
-       depends on (MIPS_ITE8172 || MIPS_IVR)
-       help
-         Say Y here to support the on-board IDE controller on the Integrated
-         Technology Express, Inc. ITE8172 SBC.  Vendor page at
-         <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
-         board at <http://www.mvista.com/partners/semiconductor/ite.html>.
-
 config BLK_DEV_IT821X
        tristate "IT821X IDE support"
        help
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 c3546fe9af63dbc718447523d116ed75ede19083..56efed6742d4d32945a1072203fea57b833d1df5 100644 (file)
@@ -145,14 +145,12 @@ int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *driv
 {
        for ( ; drive_table->id_model ; drive_table++)
                if ((!strcmp(drive_table->id_model, id->model)) &&
-                   ((strstr(drive_table->id_firmware, id->fw_rev)) ||
+                   ((strstr(id->fw_rev, drive_table->id_firmware)) ||
                     (!strcmp(drive_table->id_firmware, "ALL"))))
                        return 1;
        return 0;
 }
 
-EXPORT_SYMBOL_GPL(ide_in_drive_list);
-
 /**
  *     ide_dma_intr    -       IDE DMA interrupt handler
  *     @drive: the drive the interrupt is for
@@ -798,26 +796,23 @@ static int ide_release_dma_engine(ide_hwif_t *hwif)
 
 static int ide_release_iomio_dma(ide_hwif_t *hwif)
 {
-       if ((hwif->dma_extra) && (hwif->channel == 0))
-               release_region((hwif->dma_base + 16), hwif->dma_extra);
        release_region(hwif->dma_base, 8);
-       if (hwif->dma_base2)
-               release_region(hwif->dma_base, 8);
+       if (hwif->extra_ports)
+               release_region(hwif->extra_base, hwif->extra_ports);
        return 1;
 }
 
 /*
  * Needed for allowing full modular support of ide-driver
  */
-int ide_release_dma (ide_hwif_t *hwif)
+int ide_release_dma(ide_hwif_t *hwif)
 {
+       ide_release_dma_engine(hwif);
+
        if (hwif->mmio == 2)
                return 1;
-       if (hwif->chipset == ide_etrax100)
-               return 1;
-
-       ide_release_dma_engine(hwif);
-       return ide_release_iomio_dma(hwif);
+       else
+               return ide_release_iomio_dma(hwif);
 }
 
 static int ide_allocate_dma_engine(ide_hwif_t *hwif)
@@ -829,10 +824,9 @@ static int ide_allocate_dma_engine(ide_hwif_t *hwif)
        if (hwif->dmatable_cpu)
                return 0;
 
-       printk(KERN_ERR "%s: -- Error, unable to allocate%s DMA table(s).\n",
-                       hwif->cds->name, !hwif->dmatable_cpu ? " CPU" : "");
+       printk(KERN_ERR "%s: -- Error, unable to allocate DMA table.\n",
+              hwif->cds->name);
 
-       ide_release_dma_engine(hwif);
        return 1;
 }
 
@@ -840,9 +834,7 @@ static int ide_mapped_mmio_dma(ide_hwif_t *hwif, unsigned long base, unsigned in
 {
        printk(KERN_INFO "    %s: MMIO-DMA ", hwif->name);
 
-       hwif->dma_base = base;
-       if (hwif->cds->extra && hwif->channel == 0)
-               hwif->dma_extra = hwif->cds->extra;
+       hwif->dma_base = base;
 
        if(hwif->mate)
                hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base : base;
@@ -854,29 +846,33 @@ static int ide_mapped_mmio_dma(ide_hwif_t *hwif, unsigned long base, unsigned in
 static int ide_iomio_dma(ide_hwif_t *hwif, unsigned long base, unsigned int ports)
 {
        printk(KERN_INFO "    %s: BM-DMA at 0x%04lx-0x%04lx",
-               hwif->name, base, base + ports - 1);
+              hwif->name, base, base + ports - 1);
+
        if (!request_region(base, ports, hwif->name)) {
                printk(" -- Error, ports in use.\n");
                return 1;
        }
+
        hwif->dma_base = base;
-       if ((hwif->cds->extra) && (hwif->channel == 0)) {
-               request_region(base+16, hwif->cds->extra, hwif->cds->name);
-               hwif->dma_extra = hwif->cds->extra;
+
+       if (hwif->cds->extra) {
+               hwif->extra_base = base + (hwif->channel ? 8 : 16);
+
+               if (!hwif->mate || !hwif->mate->extra_ports) {
+                       if (!request_region(hwif->extra_base,
+                                           hwif->cds->extra, hwif->cds->name)) {
+                               printk(" -- Error, extra ports in use.\n");
+                               release_region(base, ports);
+                               return 1;
+                       }
+                       hwif->extra_ports = hwif->cds->extra;
+               }
        }
-       
+
        if(hwif->mate)
-               hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base : base;
+               hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base:base;
        else
                hwif->dma_master = base;
-       if (hwif->dma_base2) {
-               if (!request_region(hwif->dma_base2, ports, hwif->name))
-               {
-                       printk(" -- Error, secondary ports in use.\n");
-                       release_region(base, ports);
-                       return 1;
-               }
-       }
        return 0;
 }
 
index 38479a29d3e10a4e07236c0466fc0b81b4ba4a3b..ba6039b55b41ebb348223db10dc4f9a9ea9cfd0e 100644 (file)
@@ -59,8 +59,6 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq,
 {
        int ret = 1;
 
-       BUG_ON(!blk_rq_started(rq));
-
        /*
         * if failfast is set on a request, override number of sectors and
         * complete the whole request right now
@@ -82,7 +80,8 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq,
 
        if (!end_that_request_first(rq, uptodate, nr_sectors)) {
                add_disk_randomness(rq->rq_disk);
-               blkdev_dequeue_request(rq);
+               if (!list_empty(&rq->queuelist))
+                       blkdev_dequeue_request(rq);
                HWGROUP(drive)->rq = NULL;
                end_that_request_last(rq, uptodate);
                ret = 0;
@@ -135,7 +134,8 @@ enum {
        ide_pm_flush_cache      = ide_pm_state_start_suspend,
        idedisk_pm_standby,
 
-       idedisk_pm_idle         = ide_pm_state_start_resume,
+       idedisk_pm_restore_pio  = ide_pm_state_start_resume,
+       idedisk_pm_idle,
        ide_pm_restore_dma,
 };
 
@@ -156,7 +156,10 @@ static void ide_complete_power_step(ide_drive_t *drive, struct request *rq, u8 s
        case idedisk_pm_standby:        /* Suspend step 2 (standby) complete */
                pm->pm_step = ide_pm_state_completed;
                break;
-       case idedisk_pm_idle:           /* Resume step 1 (idle) complete */
+       case idedisk_pm_restore_pio:    /* Resume step 1 complete */
+               pm->pm_step = idedisk_pm_idle;
+               break;
+       case idedisk_pm_idle:           /* Resume step 2 (idle) complete */
                pm->pm_step = ide_pm_restore_dma;
                break;
        }
@@ -170,8 +173,11 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
        memset(args, 0, sizeof(*args));
 
        if (drive->media != ide_disk) {
-               /* skip idedisk_pm_idle for ATAPI devices */
-               if (pm->pm_step == idedisk_pm_idle)
+               /*
+                * skip idedisk_pm_restore_pio and idedisk_pm_idle for ATAPI
+                * devices
+                */
+               if (pm->pm_step == idedisk_pm_restore_pio)
                        pm->pm_step = ide_pm_restore_dma;
        }
 
@@ -198,13 +204,19 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
                args->handler      = &task_no_data_intr;
                return do_rw_taskfile(drive, args);
 
-       case idedisk_pm_idle:           /* Resume step 1 (idle) */
+       case idedisk_pm_restore_pio:    /* Resume step 1 (restore PIO) */
+               if (drive->hwif->tuneproc != NULL)
+                       drive->hwif->tuneproc(drive, 255);
+               ide_complete_power_step(drive, rq, 0, 0);
+               return ide_stopped;
+
+       case idedisk_pm_idle:           /* Resume step 2 (idle) */
                args->tfRegister[IDE_COMMAND_OFFSET] = WIN_IDLEIMMEDIATE;
                args->command_type = IDE_DRIVE_TASK_NO_DATA;
                args->handler = task_no_data_intr;
                return do_rw_taskfile(drive, args);
 
-       case ide_pm_restore_dma:        /* Resume step 2 (restore DMA) */
+       case ide_pm_restore_dma:        /* Resume step 3 (restore DMA) */
                /*
                 * Right now, all we do is call hwif->ide_dma_check(drive),
                 * we could be smarter and check for current xfer_speed
@@ -1346,6 +1358,10 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
         * make sure request is sane
         */
        rq = HWGROUP(drive)->rq;
+
+       if (!rq)
+               goto out;
+
        HWGROUP(drive)->rq = NULL;
 
        rq->errors = 0;
index 77703acaec1731164c433d7ce35d2eda0ba15293..badde6331775a12208c375fb68139b0e156d9606 100644 (file)
@@ -998,6 +998,7 @@ static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive)
        }
        /* done polling */
        hwgroup->polling = 0;
+       hwgroup->resetting = 0;
        return ide_stopped;
 }
 
@@ -1057,6 +1058,7 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
                }
        }
        hwgroup->polling = 0;   /* done polling */
+       hwgroup->resetting = 0; /* done reset attempt */
        return ide_stopped;
 }
 
@@ -1143,6 +1145,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
 
        /* For an ATAPI device, first try an ATAPI SRST. */
        if (drive->media != ide_disk && !do_not_try_atapi) {
+               hwgroup->resetting = 1;
                pre_reset(drive);
                SELECT_DRIVE(drive);
                udelay (20);
@@ -1168,6 +1171,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
                return ide_stopped;
        }
 
+       hwgroup->resetting = 1;
        /*
         * Note that we also set nIEN while resetting the device,
         * to mask unwanted interrupts from the interface during the reset.
index 850ef63cc986ba695ba643f5b13483c49a430a6c..8237d89eec6e2c3ddd735369ddef750c1ea4fad3 100644 (file)
@@ -71,75 +71,96 @@ EXPORT_SYMBOL(ide_xfer_verbose);
 /**
  *     ide_dma_speed   -       compute DMA speed
  *     @drive: drive
- *     @mode; intended mode
+ *     @mode:  modes available
  *
  *     Checks the drive capabilities and returns the speed to use
- *     for the transfer. Returns -1 if the requested mode is unknown
- *     (eg PIO)
+ *     for the DMA transfer.  Returns 0 if the drive is incapable
+ *     of DMA transfers.
  */
  
 u8 ide_dma_speed(ide_drive_t *drive, u8 mode)
 {
        struct hd_driveid *id   = drive->id;
        ide_hwif_t *hwif        = HWIF(drive);
+       u8 ultra_mask, mwdma_mask, swdma_mask;
        u8 speed = 0;
 
        if (drive->media != ide_disk && hwif->atapi_dma == 0)
                return 0;
 
-       switch(mode) {
-               case 0x04:
-                       if ((id->dma_ultra & 0x0040) &&
-                           (id->dma_ultra & hwif->ultra_mask))
-                               { speed = XFER_UDMA_6; break; }
-               case 0x03:
-                       if ((id->dma_ultra & 0x0020) &&
-                           (id->dma_ultra & hwif->ultra_mask))
-                               { speed = XFER_UDMA_5; break; }
-               case 0x02:
-                       if ((id->dma_ultra & 0x0010) &&
-                           (id->dma_ultra & hwif->ultra_mask))
-                               { speed = XFER_UDMA_4; break; }
-                       if ((id->dma_ultra & 0x0008) &&
-                           (id->dma_ultra & hwif->ultra_mask))
-                               { speed = XFER_UDMA_3; break; }
-               case 0x01:
-                       if ((id->dma_ultra & 0x0004) &&
-                           (id->dma_ultra & hwif->ultra_mask))
-                               { speed = XFER_UDMA_2; break; }
-                       if ((id->dma_ultra & 0x0002) &&
-                           (id->dma_ultra & hwif->ultra_mask))
-                               { speed = XFER_UDMA_1; break; }
-                       if ((id->dma_ultra & 0x0001) &&
-                           (id->dma_ultra & hwif->ultra_mask))
-                               { speed = XFER_UDMA_0; break; }
-               case 0x00:
-                       if ((id->dma_mword & 0x0004) &&
-                           (id->dma_mword & hwif->mwdma_mask))
-                               { speed = XFER_MW_DMA_2; break; }
-                       if ((id->dma_mword & 0x0002) &&
-                           (id->dma_mword & hwif->mwdma_mask))
-                               { speed = XFER_MW_DMA_1; break; }
-                       if ((id->dma_mword & 0x0001) &&
-                           (id->dma_mword & hwif->mwdma_mask))
-                               { speed = XFER_MW_DMA_0; break; }
-                       if ((id->dma_1word & 0x0004) &&
-                           (id->dma_1word & hwif->swdma_mask))
-                               { speed = XFER_SW_DMA_2; break; }
-                       if ((id->dma_1word & 0x0002) &&
-                           (id->dma_1word & hwif->swdma_mask))
-                               { speed = XFER_SW_DMA_1; break; }
-                       if ((id->dma_1word & 0x0001) &&
-                           (id->dma_1word & hwif->swdma_mask))
-                               { speed = XFER_SW_DMA_0; break; }
-       }
+       /* Capable of UltraDMA modes? */
+       ultra_mask = id->dma_ultra & hwif->ultra_mask;
+
+       if (!(id->field_valid & 4))
+               mode = 0;       /* fallback to MW/SW DMA if no UltraDMA */
+
+       switch (mode) {
+       case 4:
+               if (ultra_mask & 0x40) {
+                       speed = XFER_UDMA_6;
+                       break;
+               }
+       case 3:
+               if (ultra_mask & 0x20) {
+                       speed = XFER_UDMA_5;
+                       break;
+               }
+       case 2:
+               if (ultra_mask & 0x10) {
+                       speed = XFER_UDMA_4;
+                       break;
+               }
+               if (ultra_mask & 0x08) {
+                       speed = XFER_UDMA_3;
+                       break;
+               }
+       case 1:
+               if (ultra_mask & 0x04) {
+                       speed = XFER_UDMA_2;
+                       break;
+               }
+               if (ultra_mask & 0x02) {
+                       speed = XFER_UDMA_1;
+                       break;
+               }
+               if (ultra_mask & 0x01) {
+                       speed = XFER_UDMA_0;
+                       break;
+               }
+       case 0:
+               mwdma_mask = id->dma_mword & hwif->mwdma_mask;
 
-//     printk("%s: %s: mode 0x%02x, speed 0x%02x\n",
-//             __FUNCTION__, drive->name, mode, speed);
+               if (mwdma_mask & 0x04) {
+                       speed = XFER_MW_DMA_2;
+                       break;
+               }
+               if (mwdma_mask & 0x02) {
+                       speed = XFER_MW_DMA_1;
+                       break;
+               }
+               if (mwdma_mask & 0x01) {
+                       speed = XFER_MW_DMA_0;
+                       break;
+               }
+
+               swdma_mask = id->dma_1word & hwif->swdma_mask;
+
+               if (swdma_mask & 0x04) {
+                       speed = XFER_SW_DMA_2;
+                       break;
+               }
+               if (swdma_mask & 0x02) {
+                       speed = XFER_SW_DMA_1;
+                       break;
+               }
+               if (swdma_mask & 0x01) {
+                       speed = XFER_SW_DMA_0;
+                       break;
+               }
+       }
 
        return speed;
 }
-
 EXPORT_SYMBOL(ide_dma_speed);
 
 
index 9cadf0106c6c781d45a2add269b0b2961a1691aa..dad9c47ebb69bb0aa667689f701301a34118c115 100644 (file)
@@ -623,6 +623,8 @@ static void hwif_release_dev (struct device *dev)
 
 static void hwif_register (ide_hwif_t *hwif)
 {
+       int ret;
+
        /* register with global device tree */
        strlcpy(hwif->gendev.bus_id,hwif->name,BUS_ID_SIZE);
        hwif->gendev.driver_data = hwif;
@@ -634,7 +636,10 @@ static void hwif_register (ide_hwif_t *hwif)
                        hwif->gendev.parent = NULL;
        }
        hwif->gendev.release = hwif_release_dev;
-       device_register(&hwif->gendev);
+       ret = device_register(&hwif->gendev);
+       if (ret < 0)
+               printk(KERN_WARNING "IDE: %s: device_register error: %d\n",
+                       __FUNCTION__, ret);
 }
 
 static int wait_hwif_ready(ide_hwif_t *hwif)
@@ -884,13 +889,19 @@ int probe_hwif_init_with_fixup(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif)
 
        if (hwif->present) {
                u16 unit = 0;
+               int ret;
+
                for (unit = 0; unit < MAX_DRIVES; ++unit) {
                        ide_drive_t *drive = &hwif->drives[unit];
                        /* For now don't attach absent drives, we may
                           want them on default or a new "empty" class
                           for hotplug reprobing ? */
                        if (drive->present) {
-                               device_register(&drive->gendev);
+                               ret = device_register(&drive->gendev);
+                               if (ret < 0)
+                                       printk(KERN_WARNING "IDE: %s: "
+                                               "device_register error: %d\n",
+                                               __FUNCTION__, ret);
                        }
                }
        }
@@ -1409,8 +1420,14 @@ int ideprobe_init (void)
                        if (hwif->chipset == ide_unknown || hwif->chipset == ide_forced)
                                hwif->chipset = ide_generic;
                        for (unit = 0; unit < MAX_DRIVES; ++unit)
-                               if (hwif->drives[unit].present)
-                                       device_register(&hwif->drives[unit].gendev);
+                               if (hwif->drives[unit].present) {
+                                       int ret = device_register(
+                                               &hwif->drives[unit].gendev);
+                                       if (ret < 0)
+                                               printk(KERN_WARNING "IDE: %s: "
+                                                       "device_register error: %d\n",
+                                                       __FUNCTION__, ret);
+                               }
                }
        }
        return 0;
index 41b74b13a00c477f2f0f498442d207ac4fefa5c3..aa049dab3d95c17609f3a1d54621f18a01896749 100644 (file)
@@ -326,15 +326,24 @@ static int ide_replace_subdriver(ide_drive_t *drive, const char *driver)
 {
        struct device *dev = &drive->gendev;
        int ret = 1;
+       int err;
 
        down_write(&dev->bus->subsys.rwsem);
        device_release_driver(dev);
        /* FIXME: device can still be in use by previous driver */
        strlcpy(drive->driver_req, driver, sizeof(drive->driver_req));
-       device_attach(dev);
+       err = device_attach(dev);
+       if (err < 0)
+               printk(KERN_WARNING "IDE: %s: device_attach error: %d\n",
+                       __FUNCTION__, err);
        drive->driver_req[0] = 0;
-       if (dev->driver == NULL)
-               device_attach(dev);
+       if (dev->driver == NULL) {
+               err = device_attach(dev);
+               if (err < 0)
+                       printk(KERN_WARNING
+                               "IDE: %s: device_attach(2) error: %d\n",
+                               __FUNCTION__, err);
+       }
        if (dev->driver && !strcmp(dev->driver->name, driver))
                ret = 0;
        up_write(&dev->bus->subsys.rwsem);
@@ -526,7 +535,12 @@ static int proc_print_driver(struct device_driver *drv, void *data)
 
 static int ide_drivers_show(struct seq_file *s, void *p)
 {
-       bus_for_each_drv(&ide_bus_type, NULL, s, proc_print_driver);
+       int err;
+
+       err = bus_for_each_drv(&ide_bus_type, NULL, s, proc_print_driver);
+       if (err < 0)
+               printk(KERN_WARNING "IDE: %s: bus_for_each_drv error: %d\n",
+                       __FUNCTION__, err);
        return 0;
 }
 
index 2b1a1389c31880b16d492f8145ddfe5ac96acd90..287a66201150a0bd32432817a4357705b767329c 100644 (file)
@@ -450,7 +450,7 @@ void ide_hwif_release_regions(ide_hwif_t *hwif)
  *     @hwif: hwif to update
  *     @tmp_hwif: template
  *
- *     Restore hwif to a previous state by copying most settngs
+ *     Restore hwif to a previous state by copying most settings
  *     from the template.
  */
 
@@ -539,9 +539,10 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
        hwif->dma_vendor3               = tmp_hwif->dma_vendor3;
        hwif->dma_prdtable              = tmp_hwif->dma_prdtable;
 
-       hwif->dma_extra                 = tmp_hwif->dma_extra;
        hwif->config_data               = tmp_hwif->config_data;
        hwif->select_data               = tmp_hwif->select_data;
+       hwif->extra_base                = tmp_hwif->extra_base;
+       hwif->extra_ports               = tmp_hwif->extra_ports;
        hwif->autodma                   = tmp_hwif->autodma;
        hwif->udma_four                 = tmp_hwif->udma_four;
        hwif->no_dsc                    = tmp_hwif->no_dsc;
@@ -550,7 +551,7 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
 }
 
 /**
- *     ide_unregister          -       free an ide interface
+ *     ide_unregister          -       free an IDE interface
  *     @index: index of interface (will change soon to a pointer)
  *
  *     Perform the final unregister of an IDE interface. At the moment
@@ -563,8 +564,8 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
  *     deadlocking the IDE layer. The shutdown callback is called
  *     before we take the lock and free resources. It is up to the
  *     caller to be sure there is no pending I/O here, and that
- *     the interfce will not be reopened (present/vanishing locking
- *     isnt yet done btw). After we commit to the final kill we
+ *     the interface will not be reopened (present/vanishing locking
+ *     isn't yet done BTW). After we commit to the final kill we
  *     call the cleanup callback with the ide locks held.
  *
  *     Unregister restores the hwif structures to the default state.
@@ -674,6 +675,9 @@ void ide_unregister(unsigned int index)
                hwif->dma_status = 0;
                hwif->dma_vendor3 = 0;
                hwif->dma_prdtable = 0;
+
+               hwif->extra_base  = 0;
+               hwif->extra_ports = 0;
        }
 
        /* copy original settings */
@@ -1360,6 +1364,11 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
 
                        spin_lock_irqsave(&ide_lock, flags);
 
+                       if (HWGROUP(drive)->resetting) {
+                               spin_unlock_irqrestore(&ide_lock, flags);
+                               return -EBUSY;
+                       }
+
                        ide_abort(drive, "drive reset");
 
                        BUG_ON(HWGROUP(drive)->handler);
@@ -1993,10 +2002,16 @@ EXPORT_SYMBOL_GPL(ide_bus_type);
  */
 static int __init ide_init(void)
 {
+       int ret;
+
        printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n");
        system_bus_speed = ide_system_bus_speed();
 
-       bus_register(&ide_bus_type);
+       ret = bus_register(&ide_bus_type);
+       if (ret < 0) {
+               printk(KERN_WARNING "IDE: bus_register error: %d\n", ret);
+               return ret;
+       }
 
        init_ide_data();
 
index 602797a4420877f6fc74e659a05b4c50be8d54d6..bef4759f70e505e7e5e401751fa3e0e990b416b1 100644 (file)
@@ -120,7 +120,7 @@ static int ide_probe(struct pcmcia_device *link)
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
     link->io.IOAddrLines = 3;
-    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
     link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
@@ -398,12 +398,17 @@ static struct pcmcia_device_id ide_ids[] = {
        PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
        PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674),
        PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2      ", 0xe37be2b5, 0x8671043b),
+       PCMCIA_DEVICE_PROD_ID12("M-Systems", "CF500", 0x7ed2ad87, 0x7a13045c),
        PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79),
        PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591),
        PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728),
        PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1),
+       PCMCIA_DEVICE_PROD_ID12("SEAGATE", "ST1", 0x87c1b330, 0xe1f30883),
+       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 f35d684edc250a662d76825714fa603ebf943ceb..fef08960aa4ce2309fa1bc31f076c0da8850dcd4 100644 (file)
@@ -12,8 +12,8 @@ obj-$(CONFIG_BLK_DEV_CY82C693)                += cy82c693.o
 obj-$(CONFIG_BLK_DEV_HPT34X)           += hpt34x.o
 obj-$(CONFIG_BLK_DEV_HPT366)           += hpt366.o
 #obj-$(CONFIG_BLK_DEV_HPT37X)          += hpt37x.o
-obj-$(CONFIG_BLK_DEV_IT8172)           += it8172.o
 obj-$(CONFIG_BLK_DEV_IT821X)           += it821x.o
+obj-$(CONFIG_BLK_DEV_JMICRON)          += jmicron.o
 obj-$(CONFIG_BLK_DEV_NS87415)          += ns87415.o
 obj-$(CONFIG_BLK_DEV_OPTI621)          += opti621.o
 obj-$(CONFIG_BLK_DEV_PDC202XX_OLD)     += pdc202xx_old.o
index 380bb28c7c54aad4a6d99eefa5931e47f1459786..ae405fa32236691a4bf10f5813317d6bd72e7513 100644 (file)
@@ -222,23 +222,23 @@ static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const ch
        unsigned long flags;
 
        dev = NULL;
-       while ((dev = pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) {
+       while ((dev = pci_get_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) {
                switch (dev->device) {
                        case PCI_DEVICE_ID_CYRIX_PCI_MASTER:
-                               master_0 = dev;
+                               master_0 = pci_dev_get(dev);
                                break;
                        case PCI_DEVICE_ID_CYRIX_5530_LEGACY:
-                               cs5530_0 = dev;
+                               cs5530_0 = pci_dev_get(dev);
                                break;
                }
        }
        if (!master_0) {
                printk(KERN_ERR "%s: unable to locate PCI MASTER function\n", name);
-               return 0;
+               goto out;
        }
        if (!cs5530_0) {
                printk(KERN_ERR "%s: unable to locate CS5530 LEGACY function\n", name);
-               return 0;
+               goto out;
        }
 
        spin_lock_irqsave(&ide_lock, flags);
@@ -296,6 +296,9 @@ static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const ch
 
        spin_unlock_irqrestore(&ide_lock, flags);
 
+out:
+       pci_dev_put(master_0);
+       pci_dev_put(cs5530_0);
        return 0;
 }
 
index 120929fbe7a37c652b0e6aa0d8189ffa1cc21990..64330c459bd47e44e78117bb28478ee1875629fb 100644 (file)
@@ -281,7 +281,7 @@ static void cy82c693_tune_drive (ide_drive_t *drive, u8 pio)
 
        /* select primary or secondary channel */
        if (hwif->index > 0) {  /* drive is on the secondary channel */
-               dev = pci_find_slot(dev->bus->number, dev->devfn+1);
+               dev = pci_get_slot(dev->bus, dev->devfn+1);
                if (!dev) {
                        printk(KERN_ERR "%s: tune_drive: "
                                "Cannot find secondary interface!\n",
@@ -500,8 +500,9 @@ static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_dev
           Function 1 is primary IDE channel, function 2 - secondary. */
         if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE &&
            PCI_FUNC(dev->devfn) == 1) {
-               dev2 = pci_find_slot(dev->bus->number, dev->devfn + 1);
+               dev2 = pci_get_slot(dev->bus, dev->devfn + 1);
                ret = ide_setup_pci_devices(dev, dev2, d);
+               /* We leak pci refs here but thats ok - we can't be unloaded */
        }
        return ret;
 }
index 78810ba982e9efb17b6713c1a12d480ec4e77491..0cb7b9b520ea198e2ca487686788620ab5ca5006 100644 (file)
 
 static int ide_generic_all;            /* Set to claim all devices */
 
-#ifndef MODULE
-static int __init ide_generic_all_on(char *unused)
-{
-       ide_generic_all = 1;
-       printk(KERN_INFO "IDE generic will claim all unknown PCI IDE storage controllers.\n");
-       return 1;
-}
-__setup("all-generic-ide", ide_generic_all_on);
-#endif
+module_param_named(all_generic_ide, ide_generic_all, bool, 0444);
+MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers.");
 
 static void __devinit init_hwif_generic (ide_hwif_t *hwif)
 {
diff --git a/drivers/ide/pci/it8172.c b/drivers/ide/pci/it8172.c
deleted file mode 100644 (file)
index 0fc89fa..0000000
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *      IT8172 IDE controller support
- *
- * Copyright 2000 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.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/pci.h>
-#include <linux/hdreg.h>
-#include <linux/ide.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-#include <asm/it8172/it8172_int.h>
-
-/*
- * Prototypes
- */
-static u8 it8172_ratemask (ide_drive_t *drive)
-{
-       return 1;
-}
-
-static void it8172_tune_drive (ide_drive_t *drive, u8 pio)
-{
-       ide_hwif_t *hwif        = HWIF(drive);
-       struct pci_dev *dev     = hwif->pci_dev;
-       int is_slave            = (&hwif->drives[1] == drive);
-       unsigned long flags;
-       u16 drive_enables;
-       u32 drive_timing;
-
-       pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
-       spin_lock_irqsave(&ide_lock, flags);
-       pci_read_config_word(dev, 0x40, &drive_enables);
-       pci_read_config_dword(dev, 0x44, &drive_timing);
-
-       /*
-        * FIX! The DIOR/DIOW pulse width and recovery times in port 0x44
-        * are being left at the default values of 8 PCI clocks (242 nsec
-        * for a 33 MHz clock). These can be safely shortened at higher
-        * PIO modes. The DIOR/DIOW pulse width and recovery times only
-        * apply to PIO modes, not to the DMA modes.
-        */
-
-       /*
-        * Enable port 0x44. The IT8172G spec is confused; it calls
-        * this register the "Slave IDE Timing Register", but in fact,
-        * it controls timing for both master and slave drives.
-        */
-       drive_enables |= 0x4000;
-
-       if (is_slave) {
-               drive_enables &= 0xc006;
-               if (pio > 1)
-                       /* enable prefetch and IORDY sample-point */
-                       drive_enables |= 0x0060;
-       } else {
-               drive_enables &= 0xc060;
-               if (pio > 1)
-                       /* enable prefetch and IORDY sample-point */
-                       drive_enables |= 0x0006;
-       }
-
-       pci_write_config_word(dev, 0x40, drive_enables);
-       spin_unlock_irqrestore(&ide_lock, flags);
-}
-
-static u8 it8172_dma_2_pio (u8 xfer_rate)
-{
-       switch(xfer_rate) {
-               case XFER_UDMA_5:
-               case XFER_UDMA_4:
-               case XFER_UDMA_3:
-               case XFER_UDMA_2:
-               case XFER_UDMA_1:
-               case XFER_UDMA_0:
-               case XFER_MW_DMA_2:
-               case XFER_PIO_4:
-                       return 4;
-               case XFER_MW_DMA_1:
-               case XFER_PIO_3:
-                       return 3;
-               case XFER_SW_DMA_2:
-               case XFER_PIO_2:
-                       return 2;
-               case XFER_MW_DMA_0:
-               case XFER_SW_DMA_1:
-               case XFER_SW_DMA_0:
-               case XFER_PIO_1:
-               case XFER_PIO_0:
-               case XFER_PIO_SLOW:
-               default:
-                       return 0;
-       }
-}
-
-static int it8172_tune_chipset (ide_drive_t *drive, u8 xferspeed)
-{
-       ide_hwif_t *hwif        = HWIF(drive);
-       struct pci_dev *dev     = hwif->pci_dev;
-       u8 speed        = ide_rate_filter(it8172_ratemask(drive), xferspeed);
-       int a_speed             = 3 << (drive->dn * 4);
-       int u_flag              = 1 << drive->dn;
-       int u_speed             = 0;
-       u8 reg48, reg4a;
-
-       pci_read_config_byte(dev, 0x48, &reg48);
-       pci_read_config_byte(dev, 0x4a, &reg4a);
-
-    /*
-     * Setting the DMA cycle time to 2 or 3 PCI clocks (60 and 91 nsec
-     * at 33 MHz PCI clock) seems to cause BadCRC errors during DMA
-     * transfers on some drives, even though both numbers meet the minimum
-     * ATAPI-4 spec of 73 and 54 nsec for UDMA 1 and 2 respectively.
-     * So the faster times are just commented out here. The good news is
-     * that the slower cycle time has very little affect on transfer
-     * performance.
-     */
-    
-       switch(speed) {
-               case XFER_UDMA_4:
-               case XFER_UDMA_2:       //u_speed = 2 << (drive->dn * 4); break;
-               case XFER_UDMA_5:
-               case XFER_UDMA_3:
-               case XFER_UDMA_1:       //u_speed = 1 << (drive->dn * 4); break;
-               case XFER_UDMA_0:       u_speed = 0 << (drive->dn * 4); break;
-               case XFER_MW_DMA_2:
-               case XFER_MW_DMA_1:
-               case XFER_MW_DMA_0:
-               case XFER_SW_DMA_2:     break;
-               case XFER_PIO_4:
-               case XFER_PIO_3:
-               case XFER_PIO_2:
-               case XFER_PIO_0:        break;
-               default:                return -1;
-       }
-
-       if (speed >= XFER_UDMA_0) {
-               pci_write_config_byte(dev, 0x48, reg48 | u_flag);
-               reg4a &= ~a_speed;
-               pci_write_config_byte(dev, 0x4a, reg4a | u_speed);
-       } else {
-               pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
-               pci_write_config_byte(dev, 0x4a, reg4a & ~a_speed);
-       }
-
-       it8172_tune_drive(drive, it8172_dma_2_pio(speed));
-       return (ide_config_drive_speed(drive, speed));
-}
-
-static int it8172_config_chipset_for_dma (ide_drive_t *drive)
-{
-       u8 speed = ide_dma_speed(drive, it8172_ratemask(drive));
-
-       if (!(speed)) {
-               u8 tspeed = ide_get_best_pio_mode(drive, 255, 4, NULL);
-               speed = it8172_dma_2_pio(XFER_PIO_0 + tspeed);
-       }
-
-       (void) it8172_tune_chipset(drive, speed);
-       return ide_dma_enable(drive);
-}
-
-static int it8172_config_drive_xfer_rate (ide_drive_t *drive)
-{
-       ide_hwif_t *hwif        = HWIF(drive);
-       struct hd_driveid *id   = drive->id;
-
-       drive->init_speed = 0;
-
-       if (id && (id->capability & 1) && drive->autodma) {
-
-               if (ide_use_dma(drive)) {
-                       if (it8172_config_chipset_for_dma(drive))
-                               return hwif->ide_dma_on(drive);
-               }
-
-               goto fast_ata_pio;
-
-       } else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
-               it8172_tune_drive(drive, 5);
-               return hwif->ide_dma_off_quietly(drive);
-       }
-       /* IORDY not supported */
-       return 0;
-}
-
-static unsigned int __devinit init_chipset_it8172 (struct pci_dev *dev, const char *name)
-{
-       unsigned char progif;
-    
-       /*
-        * Place both IDE interfaces into PCI "native" mode
-        */
-       pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
-       pci_write_config_byte(dev, PCI_CLASS_PROG, progif | 0x05);    
-
-       return IT8172_IDE_IRQ;
-}
-
-
-static void __devinit init_hwif_it8172 (ide_hwif_t *hwif)
-{
-       struct pci_dev* dev = hwif->pci_dev;
-       unsigned long cmdBase, ctrlBase;
-    
-       hwif->autodma = 0;
-       hwif->tuneproc = &it8172_tune_drive;
-       hwif->speedproc = &it8172_tune_chipset;
-
-       cmdBase = dev->resource[0].start;
-       ctrlBase = dev->resource[1].start;
-    
-       ide_init_hwif_ports(&hwif->hw, cmdBase, ctrlBase | 2, NULL);
-       memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
-       hwif->noprobe = 0;
-
-       if (!hwif->dma_base) {
-               hwif->drives[0].autotune = 1;
-               hwif->drives[1].autotune = 1;
-               return;
-       }
-
-       hwif->atapi_dma = 1;
-       hwif->ultra_mask = 0x07;
-       hwif->mwdma_mask = 0x06;
-       hwif->swdma_mask = 0x04;
-
-       hwif->ide_dma_check = &it8172_config_drive_xfer_rate;
-       if (!noautodma)
-               hwif->autodma = 1;
-       hwif->drives[0].autodma = hwif->autodma;
-       hwif->drives[1].autodma = hwif->autodma;
-}
-
-static ide_pci_device_t it8172_chipsets[] __devinitdata = {
-       {       /* 0 */
-               .name           = "IT8172G",
-               .init_chipset   = init_chipset_it8172,
-               .init_hwif      = init_hwif_it8172,
-               .channels       = 2,
-               .autodma        = AUTODMA,
-               .enablebits     = {{0x00,0x00,0x00}, {0x40,0x00,0x01}},
-               .bootable       = ON_BOARD,
-       }
-};
-
-static int __devinit it8172_init_one(struct pci_dev *dev, const struct pci_device_id *id)
-{
-        if ((!(PCI_FUNC(dev->devfn) & 1) ||
-            (!((dev->class >> 8) == PCI_CLASS_STORAGE_IDE))))
-               return -ENODEV; /* IT8172 is more than an IDE controller */
-       return ide_setup_pci_device(dev, &it8172_chipsets[id->driver_data]);
-}
-
-static struct pci_device_id it8172_pci_tbl[] = {
-       { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_IT8172G, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-       { 0, },
-};
-MODULE_DEVICE_TABLE(pci, it8172_pci_tbl);
-
-static struct pci_driver driver = {
-       .name           = "IT8172_IDE",
-       .id_table       = it8172_pci_tbl,
-       .probe          = it8172_init_one,
-};
-
-static int it8172_ide_init(void)
-{
-       return ide_pci_register_driver(&driver);
-}
-
-module_init(it8172_ide_init);
-
-MODULE_AUTHOR("SteveL@mvista.com");
-MODULE_DESCRIPTION("PCI driver module for ITE 8172 IDE");
-MODULE_LICENSE("GPL");
diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c
new file mode 100644 (file)
index 0000000..68c74bb
--- /dev/null
@@ -0,0 +1,269 @@
+
+/*
+ * Copyright (C) 2006          Red Hat <alan@redhat.com>
+ *
+ *  May be copied or modified under the terms of the GNU General Public License
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/hdreg.h>
+#include <linux/ide.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+
+typedef enum {
+       PORT_PATA0 = 0,
+       PORT_PATA1 = 1,
+       PORT_SATA = 2,
+} port_type;
+
+/**
+ *     jmicron_ratemask        -       Compute available modes
+ *     @drive: IDE drive
+ *
+ *     Compute the available speeds for the devices on the interface. This
+ *     is all modes to ATA133 clipped by drive cable setup.
+ */
+
+static u8 jmicron_ratemask(ide_drive_t *drive)
+{
+       u8 mode = 4;
+       if (!eighty_ninty_three(drive))
+               mode = min(mode, (u8)1);
+       return mode;
+}
+
+/**
+ *     ata66_jmicron           -       Cable check
+ *     @hwif: IDE port
+ *
+ *     Return 1 if the cable is 80pin
+ */
+
+static int __devinit ata66_jmicron(ide_hwif_t *hwif)
+{
+       struct pci_dev *pdev = hwif->pci_dev;
+
+       u32 control;
+       u32 control5;
+
+       int port = hwif->channel;
+       port_type port_map[2];
+
+       pci_read_config_dword(pdev, 0x40, &control);
+
+       /* There are two basic mappings. One has the two SATA ports merged
+          as master/slave and the secondary as PATA, the other has only the
+          SATA port mapped */
+       if (control & (1 << 23)) {
+               port_map[0] = PORT_SATA;
+               port_map[1] = PORT_PATA0;
+       } else {
+               port_map[0] = PORT_SATA;
+               port_map[1] = PORT_SATA;
+       }
+
+       /* The 365/366 may have this bit set to map the second PATA port
+          as the internal primary channel */
+       pci_read_config_dword(pdev, 0x80, &control5);
+       if (control5 & (1<<24))
+               port_map[0] = PORT_PATA1;
+
+       /* The two ports may then be logically swapped by the firmware */
+       if (control & (1 << 22))
+               port = port ^ 1;
+
+       /*
+        *      Now we know which physical port we are talking about we can
+        *      actually do our cable checking etc. Thankfully we don't need
+        *      to do the plumbing for other cases.
+        */
+       switch (port_map[port])
+       {
+       case PORT_PATA0:
+               if (control & (1 << 3)) /* 40/80 pin primary */
+                       return 1;
+               return 0;
+       case PORT_PATA1:
+               if (control5 & (1 << 19))       /* 40/80 pin secondary */
+                       return 0;
+               return 1;
+       case PORT_SATA:
+               return 1;
+       }
+}
+
+static void jmicron_tuneproc (ide_drive_t *drive, byte mode_wanted)
+{
+       return;
+}
+
+/**
+ *     config_jmicron_chipset_for_pio  -       set drive timings
+ *     @drive: drive to tune
+ *     @speed we want
+ *
+ */
+
+static void config_jmicron_chipset_for_pio (ide_drive_t *drive, byte set_speed)
+{
+       u8 speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL);
+       if (set_speed)
+               (void) ide_config_drive_speed(drive, speed);
+}
+
+/**
+ *     jmicron_tune_chipset    -       set controller timings
+ *     @drive: Drive to set up
+ *     @xferspeed: speed we want to achieve
+ *
+ *     As the JMicron snoops for timings all we actually need to do is
+ *     make sure we don't set an invalid mode. We do need to honour
+ *     the cable detect here.
+ */
+
+static int jmicron_tune_chipset (ide_drive_t *drive, byte xferspeed)
+{
+
+       u8 speed                = ide_rate_filter(jmicron_ratemask(drive), xferspeed);
+
+       return ide_config_drive_speed(drive, speed);
+}
+
+/**
+ *     config_chipset_for_dma  -       configure for DMA
+ *     @drive: drive to configure
+ *
+ *     As the JMicron snoops for timings all we actually need to do is
+ *     make sure we don't set an invalid mode.
+ */
+
+static int config_chipset_for_dma (ide_drive_t *drive)
+{
+       u8 speed        = ide_dma_speed(drive, jmicron_ratemask(drive));
+
+       config_jmicron_chipset_for_pio(drive, !speed);
+       jmicron_tune_chipset(drive, speed);
+       return ide_dma_enable(drive);
+}
+
+/**
+ *     jmicron_configure_drive_for_dma -       set up for DMA transfers
+ *     @drive: drive we are going to set up
+ *
+ *     As the JMicron snoops for timings all we actually need to do is
+ *     make sure we don't set an invalid mode.
+ */
+
+static int jmicron_config_drive_for_dma (ide_drive_t *drive)
+{
+       ide_hwif_t *hwif        = drive->hwif;
+
+       if (ide_use_dma(drive)) {
+               if (config_chipset_for_dma(drive))
+                       return hwif->ide_dma_on(drive);
+       }
+       config_jmicron_chipset_for_pio(drive, 1);
+       return hwif->ide_dma_off_quietly(drive);
+}
+
+/**
+ *     init_hwif_jmicron       -       set up hwif structs
+ *     @hwif: interface to set up
+ *
+ *     Minimal set up is required for the Jmicron hardware.
+ */
+
+static void __devinit init_hwif_jmicron(ide_hwif_t *hwif)
+{
+       hwif->speedproc = &jmicron_tune_chipset;
+       hwif->tuneproc  = &jmicron_tuneproc;
+
+       hwif->drives[0].autotune = 1;
+       hwif->drives[1].autotune = 1;
+
+       if (!hwif->dma_base)
+               goto fallback;
+
+       hwif->atapi_dma = 1;
+       hwif->ultra_mask = 0x7f;
+       hwif->mwdma_mask = 0x07;
+
+       hwif->ide_dma_check = &jmicron_config_drive_for_dma;
+       if (!(hwif->udma_four))
+               hwif->udma_four = ata66_jmicron(hwif);
+
+       hwif->autodma = 1;
+       hwif->drives[0].autodma = hwif->autodma;
+       hwif->drives[1].autodma = hwif->autodma;
+       return;
+fallback:
+       hwif->autodma = 0;
+       return;
+}
+
+#define DECLARE_JMB_DEV(name_str)                      \
+       {                                               \
+               .name           = name_str,             \
+               .init_hwif      = init_hwif_jmicron,    \
+               .channels       = 2,                    \
+               .autodma        = AUTODMA,              \
+               .bootable       = ON_BOARD,             \
+               .enablebits     = { {0x40, 1, 1}, {0x40, 0x10, 0x10} }, \
+       }
+
+static ide_pci_device_t jmicron_chipsets[] __devinitdata = {
+       /* 0 */ DECLARE_JMB_DEV("JMB361"),
+       /* 1 */ DECLARE_JMB_DEV("JMB363"),
+       /* 2 */ DECLARE_JMB_DEV("JMB365"),
+       /* 3 */ DECLARE_JMB_DEV("JMB366"),
+       /* 4 */ DECLARE_JMB_DEV("JMB368"),
+};
+
+/**
+ *     jmicron_init_one        -       pci layer discovery entry
+ *     @dev: PCI device
+ *     @id: ident table entry
+ *
+ *     Called by the PCI code when it finds a Jmicron controller.
+ *     We then use the IDE PCI generic helper to do most of the work.
+ */
+
+static int __devinit jmicron_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+{
+       ide_setup_pci_device(dev, &jmicron_chipsets[id->driver_data]);
+       return 0;
+}
+
+static struct pci_device_id jmicron_pci_tbl[] = {
+       { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361), 0},
+       { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363), 1},
+       { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365), 2},
+       { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366), 3},
+       { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368), 4},
+       { 0, },
+};
+
+MODULE_DEVICE_TABLE(pci, jmicron_pci_tbl);
+
+static struct pci_driver driver = {
+       .name           = "JMicron IDE",
+       .id_table       = jmicron_pci_tbl,
+       .probe          = jmicron_init_one,
+};
+
+static int __init jmicron_ide_init(void)
+{
+       return ide_pci_register_driver(&driver);
+}
+
+module_init(jmicron_ide_init);
+
+MODULE_AUTHOR("Alan Cox");
+MODULE_DESCRIPTION("PCI driver module for the JMicron in legacy modes");
+MODULE_LICENSE("GPL");
index b46022a11bef82a2576d0e684282780ba814e0d6..184cdacddeb6b7ff8acf0f8967cbdd2656e75e9a 100644 (file)
@@ -154,7 +154,8 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed)
        u8                      AP, BP, CP, DP;
        u8                      TA = 0, TB = 0, TC = 0;
 
-       if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0))
+       if (drive->media != ide_disk &&
+               drive->media != ide_cdrom && speed < XFER_SW_DMA_0)
                return -1;
 
        pci_read_config_dword(dev, drive_pci, &drive_conf);
@@ -330,14 +331,12 @@ static int config_chipset_for_dma (ide_drive_t *drive)
 
 chipset_is_set:
 
-       if (drive->media == ide_disk) {
-               pci_read_config_byte(dev, (drive_pci), &AP);
-               if (id->capability & 4) /* IORDY_EN */
-                       pci_write_config_byte(dev, (drive_pci), AP|IORDY_EN);
-               pci_read_config_byte(dev, (drive_pci), &AP);
-               if (drive->media == ide_disk)   /* PREFETCH_EN */
-                       pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN);
-       }
+       pci_read_config_byte(dev, (drive_pci), &AP);
+       if (id->capability & 4) /* IORDY_EN */
+               pci_write_config_byte(dev, (drive_pci), AP|IORDY_EN);
+       pci_read_config_byte(dev, (drive_pci), &AP);
+       if (drive->media == ide_disk)   /* PREFETCH_EN */
+               pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN);
 
        speed = ide_dma_speed(drive, pdc202xx_ratemask(drive));
 
@@ -385,7 +384,7 @@ static void pdc202xx_old_ide_dma_start(ide_drive_t *drive)
 {
        if (drive->current_speed > XFER_UDMA_2)
                pdc_old_enable_66MHz_clock(drive->hwif);
-       if (drive->addressing == 1) {
+       if (drive->media != ide_disk || drive->addressing == 1) {
                struct request *rq      = HWGROUP(drive)->rq;
                ide_hwif_t *hwif        = HWIF(drive);
                unsigned long high_16   = hwif->dma_master;
@@ -405,7 +404,7 @@ static void pdc202xx_old_ide_dma_start(ide_drive_t *drive)
 
 static int pdc202xx_old_ide_dma_end(ide_drive_t *drive)
 {
-       if (drive->addressing == 1) {
+       if (drive->media != ide_disk || drive->addressing == 1) {
                ide_hwif_t *hwif        = HWIF(drive);
                unsigned long high_16   = hwif->dma_master;
                unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20);
@@ -519,6 +518,7 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif)
        hwif->ultra_mask = 0x3f;
        hwif->mwdma_mask = 0x07;
        hwif->swdma_mask = 0x07;
+       hwif->atapi_dma = 1;
 
        hwif->err_stops_fifo = 1;
 
index eb5bab1890cd1d484b553597e0ced72962da8f1b..cdc3aab9ebcbc46676c76f6e5569f13eb214505a 100644 (file)
@@ -222,13 +222,15 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio)
        u16 master_data;
        u8 slave_data;
        static DEFINE_SPINLOCK(tune_lock);
+       int control = 0;
 
                                 /* ISP  RTC */
-       u8 timings[][2] = { { 0, 0 },
-                           { 0, 0 },
-                           { 1, 0 },
-                           { 2, 1 },
-                           { 2, 3 }, };
+       static const u8 timings[][2]= {
+                                       { 0, 0 },
+                                       { 0, 0 },
+                                       { 1, 0 },
+                                       { 2, 1 },
+                                       { 2, 3 }, };
 
        pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
 
@@ -239,19 +241,30 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio)
         */
        spin_lock_irqsave(&tune_lock, flags);
        pci_read_config_word(dev, master_port, &master_data);
+
+       if (pio >= 2)
+               control |= 1;   /* Programmable timing on */
+       if (drive->media == ide_disk)
+               control |= 4;   /* Prefetch, post write */
+       if (pio >= 3)
+               control |= 2;   /* IORDY */
        if (is_slave) {
                master_data = master_data | 0x4000;
-               if (pio > 1)
+               if (pio > 1) {
                        /* enable PPE, IE and TIME */
-                       master_data = master_data | 0x0070;
+                       master_data = master_data | (control << 4);
+               } else {
+                       master_data &= ~0x0070;
+               }
                pci_read_config_byte(dev, slave_port, &slave_data);
                slave_data = slave_data & (hwif->channel ? 0x0f : 0xf0);
                slave_data = slave_data | (((timings[pio][0] << 2) | timings[pio][1]) << (hwif->channel ? 4 : 0));
        } else {
                master_data = master_data & 0xccf8;
-               if (pio > 1)
+               if (pio > 1) {
                        /* enable PPE, IE and TIME */
-                       master_data = master_data | 0x0007;
+                       master_data = master_data | control;
+               }
                master_data = master_data | (timings[pio][0] << 12) | (timings[pio][1] << 8);
        }
        pci_write_config_word(dev, master_port, master_data);
index fc2b5496b6d251a611bd3200baf733d8263e1f23..ff80937d94ddd307c6c2974f058980ee71273285 100644 (file)
@@ -323,6 +323,7 @@ static void sc1200_tuneproc (ide_drive_t *drive, byte pio)  /* mode=255 means "au
        }
 }
 
+#ifdef CONFIG_PM
 static ide_hwif_t *lookup_pci_dev (ide_hwif_t *prev, struct pci_dev *dev)
 {
        int     h;
@@ -451,6 +452,7 @@ static int sc1200_resume (struct pci_dev *dev)
        }
        return 0;
 }
+#endif
 
 /*
  * This gets invoked by the IDE driver once for each channel,
@@ -499,8 +501,10 @@ static struct pci_driver driver = {
        .name           = "SC1200_IDE",
        .id_table       = sc1200_pci_tbl,
        .probe          = sc1200_init_one,
+#ifdef CONFIG_PM
        .suspend        = sc1200_suspend,
        .resume         = sc1200_resume,
+#endif
 };
 
 static int sc1200_ide_init(void)
index d8a0d87df734bb22f383b540b5291991ffef99fa..f3fe287fbd89ba6b5d65deb92b42ba1ca9f875e2 100644 (file)
@@ -220,7 +220,7 @@ sgiioc4_ide_dma_end(ide_drive_t * drive)
        ide_hwif_t *hwif = HWIF(drive);
        u64 dma_base = hwif->dma_base;
        int dma_stat = 0;
-       unsigned long *ending_dma = (unsigned long *) hwif->dma_base2;
+       unsigned long *ending_dma = ide_get_hwifdata(hwif);
 
        hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4);
 
@@ -369,6 +369,7 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
 {
        void __iomem *virt_dma_base;
        int num_ports = sizeof (ioc4_dma_regs_t);
+       void *pad;
 
        printk(KERN_INFO "%s: BM-DMA at 0x%04lx-0x%04lx\n", hwif->name,
               dma_base, dma_base + num_ports - 1);
@@ -400,17 +401,14 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
 
        hwif->sg_max_nents = IOC4_PRD_ENTRIES;
 
-       hwif->dma_base2 = (unsigned long)
-               pci_alloc_consistent(hwif->pci_dev,
-                                    IOC4_IDE_CACHELINE_SIZE,
-                                    (dma_addr_t *) &(hwif->dma_status));
+       pad = pci_alloc_consistent(hwif->pci_dev, IOC4_IDE_CACHELINE_SIZE,
+                                  (dma_addr_t *) &(hwif->dma_status));
 
-       if (!hwif->dma_base2)
-               goto dma_base2alloc_failure;
-
-       return;
+       if (pad) {
+               ide_set_hwifdata(hwif, pad);
+               return;
+       }
 
-dma_base2alloc_failure:
        pci_free_consistent(hwif->pci_dev,
                            IOC4_PRD_ENTRIES * IOC4_PRD_BYTES,
                            hwif->dmatable_cpu, hwif->dmatable_dma);
@@ -476,7 +474,7 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
        hwif->OUTL(dma_addr, dma_base + IOC4_DMA_PTR_L * 4);
 
        /* Address of the Ending DMA */
-       memset((unsigned int *) hwif->dma_base2, 0, IOC4_IDE_CACHELINE_SIZE);
+       memset(ide_get_hwifdata(hwif), 0, IOC4_IDE_CACHELINE_SIZE);
        ending_dma_addr = cpu_to_le32(hwif->dma_status);
        hwif->OUTL(ending_dma_addr, dma_base + IOC4_DMA_END_ADDR * 4);
 
index 20b392948f366ac9a5767f2226eb5f2d44f7be52..697f566fb90ae02b87c44d47a62b3ac6dc8f0d48 100644 (file)
@@ -898,7 +898,6 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif)
                base = (unsigned long) addr;
 
        hwif->dma_base                  = base + (ch ? 0x08 : 0x00);
-       hwif->dma_base2                 = base + (ch ? 0x18 : 0x10);
        hwif->mmio                      = 2;
 }
 
index 9b7589e8e93e52e13316aea9a501e21082100618..2af634d7acf4a86de888b7077e037c5e5a4a0fe7 100644 (file)
@@ -248,7 +248,7 @@ static struct via_isa_bridge *via_config_find(struct pci_dev **isa)
        u8 t;
 
        for (via_config = via_isa_bridges; via_config->id; via_config++)
-               if ((*isa = pci_find_device(PCI_VENDOR_ID_VIA +
+               if ((*isa = pci_get_device(PCI_VENDOR_ID_VIA +
                        !!(via_config->flags & VIA_BAD_ID),
                        via_config->id, NULL))) {
 
@@ -256,6 +256,7 @@ static struct via_isa_bridge *via_config_find(struct pci_dev **isa)
                        if (t >= via_config->rev_min &&
                            t <= via_config->rev_max)
                                break;
+                       pci_dev_put(*isa);
                }
 
        return via_config;
@@ -283,6 +284,7 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const
        via_config = via_config_find(&isa);
        if (!via_config->id) {
                printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n");
+               pci_dev_put(isa);
                return -ENODEV;
        }
 
@@ -361,6 +363,7 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const
                via_dma[via_config->flags & VIA_UDMA],
                pci_name(dev));
 
+       pci_dev_put(isa);
        return 0;
 }
 
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 eb0945284accec16b4c0ff0075c504da59f34a35..0719b6484824cd6075923ef0b322a417a1713f47 100644 (file)
@@ -101,7 +101,7 @@ static ide_hwif_t *ide_match_hwif(unsigned long io_base, u8 bootable, const char
                                return hwif;    /* pick an unused entry */
                }
        }
-       for (h = 0; h < 2; ++h) {
+       for (h = 0; h < 2 && h < MAX_HWIFS; ++h) {
                hwif = ide_hwifs + h;
                if (hwif->chipset == ide_unknown)
                        return hwif;    /* pick an unused entry */
@@ -794,24 +794,6 @@ int __ide_pci_register_driver(struct pci_driver *driver, struct module *module)
 
 EXPORT_SYMBOL_GPL(__ide_pci_register_driver);
 
-/**
- *     ide_unregister_pci_driver       -       unregister an IDE driver
- *     @driver: driver to remove
- *
- *     Unregister a currently installed IDE driver. Returns are the same
- *     as for pci_unregister_driver
- */
-void ide_pci_unregister_driver(struct pci_driver *driver)
-{
-       if(!pre_init)
-               pci_unregister_driver(driver);
-       else
-               list_del(&driver->node);
-}
-
-EXPORT_SYMBOL_GPL(ide_pci_unregister_driver);
-
 /**
  *     ide_scan_pcidev         -       find an IDE driver for a device
  *     @dev: PCI device to check
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 1178bd434d1b1f12cd41f32bbbb0c5aaa3a50929..9ae4f3a67c704639bfee110773d22c58d536ea2c 100644 (file)
@@ -874,23 +874,25 @@ static struct rdma_id_private *cma_new_id(struct rdma_cm_id *listen_id,
        __u16 port;
        u8 ip_ver;
 
+       if (cma_get_net_info(ib_event->private_data, listen_id->ps,
+                            &ip_ver, &port, &src, &dst))
+               goto err;
+
        id = rdma_create_id(listen_id->event_handler, listen_id->context,
                            listen_id->ps);
        if (IS_ERR(id))
-               return NULL;
+               goto err;
+
+       cma_save_net_info(&id->route.addr, &listen_id->route.addr,
+                         ip_ver, port, src, dst);
 
        rt = &id->route;
        rt->num_paths = ib_event->param.req_rcvd.alternate_path ? 2 : 1;
-       rt->path_rec = kmalloc(sizeof *rt->path_rec * rt->num_paths, GFP_KERNEL);
+       rt->path_rec = kmalloc(sizeof *rt->path_rec * rt->num_paths,
+                              GFP_KERNEL);
        if (!rt->path_rec)
-               goto err;
+               goto destroy_id;
 
-       if (cma_get_net_info(ib_event->private_data, listen_id->ps,
-                            &ip_ver, &port, &src, &dst))
-               goto err;
-
-       cma_save_net_info(&id->route.addr, &listen_id->route.addr,
-                         ip_ver, port, src, dst);
        rt->path_rec[0] = *ib_event->param.req_rcvd.primary_path;
        if (rt->num_paths == 2)
                rt->path_rec[1] = *ib_event->param.req_rcvd.alternate_path;
@@ -903,8 +905,10 @@ static struct rdma_id_private *cma_new_id(struct rdma_cm_id *listen_id,
        id_priv = container_of(id, struct rdma_id_private, id);
        id_priv->state = CMA_CONNECT;
        return id_priv;
-err:
+
+destroy_id:
        rdma_destroy_id(id);
+err:
        return NULL;
 }
 
@@ -932,6 +936,7 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
        mutex_unlock(&lock);
        if (ret) {
                ret = -ENODEV;
+               cma_exch(conn_id, CMA_DESTROYING);
                cma_release_remove(conn_id);
                rdma_destroy_id(&conn_id->id);
                goto out;
@@ -1307,6 +1312,7 @@ static void cma_query_handler(int status, struct ib_sa_path_rec *path_rec,
                work->old_state = CMA_ROUTE_QUERY;
                work->new_state = CMA_ADDR_RESOLVED;
                work->event.event = RDMA_CM_EVENT_ROUTE_ERROR;
+               work->event.status = status;
        }
 
        queue_work(cma_wq, &work->work);
@@ -1862,6 +1868,11 @@ static int cma_connect_ib(struct rdma_id_private *id_priv,
 
        ret = ib_send_cm_req(id_priv->cm_id.ib, &req);
 out:
+       if (ret && !IS_ERR(id_priv->cm_id.ib)) {
+               ib_destroy_cm_id(id_priv->cm_id.ib);
+               id_priv->cm_id.ib = NULL;
+       }
+
        kfree(private_data);
        return ret;
 }
@@ -1889,10 +1900,8 @@ static int cma_connect_iw(struct rdma_id_private *id_priv,
        cm_id->remote_addr = *sin;
 
        ret = cma_modify_qp_rtr(&id_priv->id);
-       if (ret) {
-               iw_destroy_cm_id(cm_id);
-               return ret;
-       }
+       if (ret)
+               goto out;
 
        iw_param.ord = conn_param->initiator_depth;
        iw_param.ird = conn_param->responder_resources;
@@ -1904,6 +1913,10 @@ static int cma_connect_iw(struct rdma_id_private *id_priv,
                iw_param.qpn = conn_param->qp_num;
        ret = iw_cm_connect(cm_id, &iw_param);
 out:
+       if (ret && !IS_ERR(cm_id)) {
+               iw_destroy_cm_id(cm_id);
+               id_priv->cm_id.iw = NULL;
+       }
        return ret;
 }
 
@@ -2142,12 +2155,9 @@ static int cma_remove_id_dev(struct rdma_id_private *id_priv)
 
 static void cma_process_remove(struct cma_device *cma_dev)
 {
-       struct list_head remove_list;
        struct rdma_id_private *id_priv;
        int ret;
 
-       INIT_LIST_HEAD(&remove_list);
-
        mutex_lock(&lock);
        while (!list_empty(&cma_dev->id_list)) {
                id_priv = list_entry(cma_dev->id_list.next,
@@ -2158,8 +2168,7 @@ static void cma_process_remove(struct cma_device *cma_dev)
                        continue;
                }
 
-               list_del(&id_priv->list);
-               list_add_tail(&id_priv->list, &remove_list);
+               list_del_init(&id_priv->list);
                atomic_inc(&id_priv->refcount);
                mutex_unlock(&lock);
 
index 2380994418a5f193db4cafc769fe2d2945ade8c5..024d511c4b58f3c64140d8d5d1a4b236cff6ddca 100644 (file)
@@ -49,7 +49,7 @@
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>");
 MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver");
-MODULE_VERSION("SVNEHCA_0016");
+MODULE_VERSION("SVNEHCA_0017");
 
 int ehca_open_aqp1     = 0;
 int ehca_debug_level   = 0;
@@ -239,7 +239,7 @@ init_node_guid1:
        return ret;
 }
 
-int ehca_register_device(struct ehca_shca *shca)
+int ehca_init_device(struct ehca_shca *shca)
 {
        int ret;
 
@@ -317,11 +317,6 @@ int ehca_register_device(struct ehca_shca *shca)
        /* shca->ib_device.process_mad      = ehca_process_mad;     */
        shca->ib_device.mmap                = ehca_mmap;
 
-       ret = ib_register_device(&shca->ib_device);
-       if (ret)
-               ehca_err(&shca->ib_device,
-                        "ib_register_device() failed ret=%x", ret);
-
        return ret;
 }
 
@@ -561,9 +556,9 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
                goto probe1;
        }
 
-       ret = ehca_register_device(shca);
+       ret = ehca_init_device(shca);
        if (ret) {
-               ehca_gen_err("Cannot register Infiniband device");
+               ehca_gen_err("Cannot init ehca  device struct");
                goto probe1;
        }
 
@@ -571,7 +566,7 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
        ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, 2048);
        if (ret) {
                ehca_err(&shca->ib_device, "Cannot create EQ.");
-               goto probe2;
+               goto probe1;
        }
 
        ret = ehca_create_eq(shca, &shca->neq, EHCA_NEQ, 513);
@@ -600,6 +595,13 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
                goto probe5;
        }
 
+       ret = ib_register_device(&shca->ib_device);
+       if (ret) {
+               ehca_err(&shca->ib_device,
+                        "ib_register_device() failed ret=%x", ret);
+               goto probe6;
+       }
+
        /* create AQP1 for port 1 */
        if (ehca_open_aqp1 == 1) {
                shca->sport[0].port_state = IB_PORT_DOWN;
@@ -607,7 +609,7 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
                if (ret) {
                        ehca_err(&shca->ib_device,
                                 "Cannot create AQP1 for port 1.");
-                       goto probe6;
+                       goto probe7;
                }
        }
 
@@ -618,7 +620,7 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
                if (ret) {
                        ehca_err(&shca->ib_device,
                                 "Cannot create AQP1 for port 2.");
-                       goto probe7;
+                       goto probe8;
                }
        }
 
@@ -630,12 +632,15 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
 
        return 0;
 
-probe7:
+probe8:
        ret = ehca_destroy_aqp1(&shca->sport[0]);
        if (ret)
                ehca_err(&shca->ib_device,
                         "Cannot destroy AQP1 for port 1. ret=%x", ret);
 
+probe7:
+       ib_unregister_device(&shca->ib_device);
+
 probe6:
        ret = ehca_dereg_internal_maxmr(shca);
        if (ret)
@@ -660,9 +665,6 @@ probe3:
                ehca_err(&shca->ib_device,
                         "Cannot destroy EQ. ret=%x", ret);
 
-probe2:
-       ib_unregister_device(&shca->ib_device);
-
 probe1:
        ib_dealloc_device(&shca->ib_device);
 
@@ -750,7 +752,7 @@ int __init ehca_module_init(void)
        int ret;
 
        printk(KERN_INFO "eHCA Infiniband Device Driver "
-                        "(Rel.: SVNEHCA_0016)\n");
+                        "(Rel.: SVNEHCA_0017)\n");
        idr_init(&ehca_qp_idr);
        idr_init(&ehca_cq_idr);
        spin_lock_init(&ehca_qp_idr_lock);
index 9f56bb846d93bab73b190ab09e4b3bc691d3e91d..809da3ef706bd72959a26bd2fed842fcbcb239f3 100644 (file)
@@ -117,7 +117,7 @@ extern int ehca_debug_level;
                unsigned int l = (unsigned int)(len); \
                unsigned char *deb = (unsigned char*)(adr);     \
                for (x = 0; x < l; x += 16) { \
-                       printk("EHCA_DMP:%s" format \
+                       printk("EHCA_DMP:%s " format \
                               " adr=%p ofs=%04x %016lx %016lx\n", \
                               __FUNCTION__, ##args, deb, x, \
                               *((u64 *)&deb[0]), *((u64 *)&deb[8])); \
index a504cf67f27274b2f8cd622884a09e519f7e410e..ce6038743c5c258bd7b06bbaf62d77a7d6ab4bbe 100644 (file)
@@ -241,10 +241,7 @@ int ipath_make_rc_req(struct ipath_qp *qp,
                 * original work request since we may need to resend
                 * it.
                 */
-               qp->s_sge.sge = wqe->sg_list[0];
-               qp->s_sge.sg_list = wqe->sg_list + 1;
-               qp->s_sge.num_sge = wqe->wr.num_sge;
-               qp->s_len = len = wqe->length;
+               len = wqe->length;
                ss = &qp->s_sge;
                bth2 = 0;
                switch (wqe->wr.opcode) {
@@ -368,14 +365,23 @@ int ipath_make_rc_req(struct ipath_qp *qp,
                default:
                        goto done;
                }
+               qp->s_sge.sge = wqe->sg_list[0];
+               qp->s_sge.sg_list = wqe->sg_list + 1;
+               qp->s_sge.num_sge = wqe->wr.num_sge;
+               qp->s_len = wqe->length;
                if (newreq) {
                        qp->s_tail++;
                        if (qp->s_tail >= qp->s_size)
                                qp->s_tail = 0;
                }
-               bth2 |= qp->s_psn++ & IPATH_PSN_MASK;
-               if ((int)(qp->s_psn - qp->s_next_psn) > 0)
-                       qp->s_next_psn = qp->s_psn;
+               bth2 |= qp->s_psn & IPATH_PSN_MASK;
+               if (wqe->wr.opcode == IB_WR_RDMA_READ)
+                       qp->s_psn = wqe->lpsn + 1;
+               else {
+                       qp->s_psn++;
+                       if ((int)(qp->s_psn - qp->s_next_psn) > 0)
+                               qp->s_next_psn = qp->s_psn;
+               }
                /*
                 * Put the QP on the pending list so lost ACKs will cause
                 * a retry.  More than one request can be pending so the
@@ -690,13 +696,6 @@ void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc)
        struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last);
        struct ipath_ibdev *dev;
 
-       /*
-        * If there are no requests pending, we are done.
-        */
-       if (ipath_cmp24(psn, qp->s_next_psn) >= 0 ||
-           qp->s_last == qp->s_tail)
-               goto done;
-
        if (qp->s_retry == 0) {
                wc->wr_id = wqe->wr.wr_id;
                wc->status = IB_WC_RETRY_EXC_ERR;
@@ -731,8 +730,6 @@ void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc)
                dev->n_rc_resends += (int)qp->s_psn - (int)psn;
 
        reset_psn(qp, psn);
-
-done:
        tasklet_hi_schedule(&qp->s_task);
 
 bail:
@@ -765,6 +762,7 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
        struct ib_wc wc;
        struct ipath_swqe *wqe;
        int ret = 0;
+       u32 ack_psn;
 
        /*
         * Remove the QP from the timeout queue (or RNR timeout queue).
@@ -777,26 +775,26 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
                list_del_init(&qp->timerwait);
        spin_unlock(&dev->pending_lock);
 
+       /* Nothing is pending to ACK/NAK. */
+       if (unlikely(qp->s_last == qp->s_tail))
+               goto bail;
+
        /*
         * Note that NAKs implicitly ACK outstanding SEND and RDMA write
         * requests and implicitly NAK RDMA read and atomic requests issued
         * before the NAK'ed request.  The MSN won't include the NAK'ed
         * request but will include an ACK'ed request(s).
         */
+       ack_psn = psn;
+       if (aeth >> 29)
+               ack_psn--;
        wqe = get_swqe_ptr(qp, qp->s_last);
 
-       /* Nothing is pending to ACK/NAK. */
-       if (qp->s_last == qp->s_tail)
-               goto bail;
-
        /*
         * The MSN might be for a later WQE than the PSN indicates so
         * only complete WQEs that the PSN finishes.
         */
-       while (ipath_cmp24(psn, wqe->lpsn) >= 0) {
-               /* If we are ACKing a WQE, the MSN should be >= the SSN. */
-               if (ipath_cmp24(aeth, wqe->ssn) < 0)
-                       break;
+       while (ipath_cmp24(ack_psn, wqe->lpsn) >= 0) {
                /*
                 * If this request is a RDMA read or atomic, and the ACK is
                 * for a later operation, this ACK NAKs the RDMA read or
@@ -807,7 +805,8 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
                 * is sent but before the response is received.
                 */
                if ((wqe->wr.opcode == IB_WR_RDMA_READ &&
-                    opcode != OP(RDMA_READ_RESPONSE_LAST)) ||
+                    (opcode != OP(RDMA_READ_RESPONSE_LAST) ||
+                      ipath_cmp24(ack_psn, wqe->lpsn) != 0)) ||
                    ((wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP ||
                      wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD) &&
                     (opcode != OP(ATOMIC_ACKNOWLEDGE) ||
@@ -825,6 +824,10 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
                         */
                        goto bail;
                }
+               if (wqe->wr.opcode == IB_WR_RDMA_READ ||
+                   wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP ||
+                   wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD)
+                       tasklet_hi_schedule(&qp->s_task);
                /* Post a send completion queue entry if requested. */
                if (!test_bit(IPATH_S_SIGNAL_REQ_WR, &qp->s_flags) ||
                    (wqe->wr.send_flags & IB_SEND_SIGNALED)) {
@@ -1055,7 +1058,8 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
                /* no AETH, no ACK */
                if (unlikely(ipath_cmp24(psn, qp->s_last_psn + 1))) {
                        dev->n_rdma_seq++;
-                       ipath_restart_rc(qp, qp->s_last_psn + 1, &wc);
+                       if (qp->s_last != qp->s_tail)
+                               ipath_restart_rc(qp, qp->s_last_psn + 1, &wc);
                        goto ack_done;
                }
        rdma_read:
@@ -1091,7 +1095,8 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
                /* ACKs READ req. */
                if (unlikely(ipath_cmp24(psn, qp->s_last_psn + 1))) {
                        dev->n_rdma_seq++;
-                       ipath_restart_rc(qp, qp->s_last_psn + 1, &wc);
+                       if (qp->s_last != qp->s_tail)
+                               ipath_restart_rc(qp, qp->s_last_psn + 1, &wc);
                        goto ack_done;
                }
                /* FALLTHROUGH */
index 42eaed88c281b2a194641c6231abc80bafa45893..a5456108dbadcae24bbfd1b753cdf77eb07a694b 100644 (file)
@@ -1601,7 +1601,7 @@ int ipath_register_ib_device(struct ipath_devdata *dd)
        dev->mmap = ipath_mmap;
 
        snprintf(dev->node_desc, sizeof(dev->node_desc),
-                IPATH_IDSTR " %s", system_utsname.nodename);
+                IPATH_IDSTR " %s", init_utsname()->nodename);
 
        ret = ib_register_device(dev);
        if (ret)
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 58223b5d842a00059c9d6b0ee30a45417fd0961a..96232313b1b97fc277aeb4c67ebff59d205eb6aa 100644 (file)
@@ -24,6 +24,20 @@ config INPUT
 
 if INPUT
 
+config INPUT_FF_MEMLESS
+       tristate "Support for memoryless force-feedback devices"
+       default n
+       ---help---
+         Say Y here if you have memoryless force-feedback input device
+         such as Logitech WingMan Force 3D, ThrustMaster FireStorm Dual
+         Power 2, or similar. You will also need to enable hardware-specific
+         driver.
+
+         If unsure, say N.
+
+         To compile this driver as a module, choose M here: the
+         module will be called ff-memless.
+
 comment "Userland interfaces"
 
 config INPUT_MOUSEDEV
index 1a6ff4982f302e124b67ad71b844131f0dabef93..a005b1df5f1a57ddc32be556f8c503d8f4f7a4fa 100644 (file)
@@ -4,7 +4,11 @@
 
 # Each configuration option enables a list of files.
 
-obj-$(CONFIG_INPUT)            += input.o
+obj-$(CONFIG_INPUT)            += input-core.o
+input-core-objs := input.o ff-core.o
+
+obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o
+
 obj-$(CONFIG_INPUT_MOUSEDEV)   += mousedev.o
 obj-$(CONFIG_INPUT_JOYDEV)     += joydev.o
 obj-$(CONFIG_INPUT_EVDEV)      += evdev.o
index 07358fb51b82aacf8e7cb1b9fbe9f2cc943eb455..5a9653c3128a0d90308e632683f2a2c9a6e077ec 100644 (file)
@@ -42,10 +42,12 @@ static char evbug_name[] = "evbug";
 
 static void evbug_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
 {
-       printk(KERN_DEBUG "evbug.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n", handle->dev->phys, type, code, value);
+       printk(KERN_DEBUG "evbug.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n",
+               handle->dev->phys, type, code, value);
 }
 
-static struct input_handle *evbug_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
+static struct input_handle *evbug_connect(struct input_handler *handler, struct input_dev *dev,
+                                         const struct input_device_id *id)
 {
        struct input_handle *handle;
 
@@ -72,7 +74,7 @@ static void evbug_disconnect(struct input_handle *handle)
        kfree(handle);
 }
 
-static struct input_device_id evbug_ids[] = {
+static const struct input_device_id evbug_ids[] = {
        { .driver_info = 1 },   /* Matches all devices */
        { },                    /* Terminating zero entry */
 };
@@ -89,8 +91,7 @@ static struct input_handler evbug_handler = {
 
 static int __init evbug_init(void)
 {
-       input_register_handler(&evbug_handler);
-       return 0;
+       return input_register_handler(&evbug_handler);
 }
 
 static void __exit evbug_exit(void)
index 4bf48188cc9114cdce3a6a97de55351db1bf9ec3..6439f378f6cc9562f23ec5f8ee331f57bd898f45 100644 (file)
@@ -391,8 +391,10 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
        struct evdev *evdev = list->evdev;
        struct input_dev *dev = evdev->handle.dev;
        struct input_absinfo abs;
+       struct ff_effect effect;
        int __user *ip = (int __user *)p;
        int i, t, u, v;
+       int error;
 
        if (!evdev->exist)
                return -ENODEV;
@@ -460,27 +462,22 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
                        return 0;
 
                case EVIOCSFF:
-                       if (dev->upload_effect) {
-                               struct ff_effect effect;
-                               int err;
-
-                               if (copy_from_user(&effect, p, sizeof(effect)))
-                                       return -EFAULT;
-                               err = dev->upload_effect(dev, &effect);
-                               if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
-                                       return -EFAULT;
-                               return err;
-                       } else
-                               return -ENOSYS;
+                       if (copy_from_user(&effect, p, sizeof(effect)))
+                               return -EFAULT;
 
-               case EVIOCRMFF:
-                       if (!dev->erase_effect)
-                               return -ENOSYS;
+                       error = input_ff_upload(dev, &effect, file);
 
-                       return dev->erase_effect(dev, (int)(unsigned long) p);
+                       if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
+                               return -EFAULT;
+
+                       return error;
+
+               case EVIOCRMFF:
+                       return input_ff_erase(dev, (int)(unsigned long) p, file);
 
                case EVIOCGEFFECTS:
-                       if (put_user(dev->ff_effects_max, ip))
+                       i = test_bit(EV_FF, dev->evbit) ? dev->ff->max_effects : 0;
+                       if (put_user(i, ip))
                                return -EFAULT;
                        return 0;
 
@@ -604,7 +601,7 @@ static long evdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned lon
 }
 #endif
 
-static struct file_operations evdev_fops = {
+static const struct file_operations evdev_fops = {
        .owner =        THIS_MODULE,
        .read =         evdev_read,
        .write =        evdev_write,
@@ -619,7 +616,8 @@ static struct file_operations evdev_fops = {
        .flush =        evdev_flush
 };
 
-static struct input_handle *evdev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
+static struct input_handle *evdev_connect(struct input_handler *handler, struct input_dev *dev,
+                                         const struct input_device_id *id)
 {
        struct evdev *evdev;
        struct class_device *cdev;
@@ -669,6 +667,7 @@ static void evdev_disconnect(struct input_handle *handle)
        evdev->exist = 0;
 
        if (evdev->open) {
+               input_flush_device(handle, NULL);
                input_close_device(handle);
                wake_up_interruptible(&evdev->wait);
                list_for_each_entry(list, &evdev->list, node)
@@ -677,7 +676,7 @@ static void evdev_disconnect(struct input_handle *handle)
                evdev_free(evdev);
 }
 
-static struct input_device_id evdev_ids[] = {
+static const struct input_device_id evdev_ids[] = {
        { .driver_info = 1 },   /* Matches all devices */
        { },                    /* Terminating zero entry */
 };
@@ -696,8 +695,7 @@ static struct input_handler evdev_handler = {
 
 static int __init evdev_init(void)
 {
-       input_register_handler(&evdev_handler);
-       return 0;
+       return input_register_handler(&evdev_handler);
 }
 
 static void __exit evdev_exit(void)
diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c
new file mode 100644 (file)
index 0000000..35656ca
--- /dev/null
@@ -0,0 +1,367 @@
+/*
+ *  Force feedback support for Linux input subsystem
+ *
+ *  Copyright (c) 2006 Anssi Hannula <anssi.hannula@gmail.com>
+ *  Copyright (c) 2006 Dmitry Torokhov <dtor@mail.ru>
+ */
+
+/*
+ * 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
+ */
+
+/* #define DEBUG */
+
+#define debug(format, arg...) pr_debug("ff-core: " format "\n", ## arg)
+
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+
+/*
+ * Check that the effect_id is a valid effect and whether the user
+ * is the owner
+ */
+static int check_effect_access(struct ff_device *ff, int effect_id,
+                               struct file *file)
+{
+       if (effect_id < 0 || effect_id >= ff->max_effects ||
+           !ff->effect_owners[effect_id])
+               return -EINVAL;
+
+       if (file && ff->effect_owners[effect_id] != file)
+               return -EACCES;
+
+       return 0;
+}
+
+/*
+ * Checks whether 2 effects can be combined together
+ */
+static inline int check_effects_compatible(struct ff_effect *e1,
+                                          struct ff_effect *e2)
+{
+       return e1->type == e2->type &&
+              (e1->type != FF_PERIODIC ||
+               e1->u.periodic.waveform == e2->u.periodic.waveform);
+}
+
+/*
+ * Convert an effect into compatible one
+ */
+static int compat_effect(struct ff_device *ff, struct ff_effect *effect)
+{
+       int magnitude;
+
+       switch (effect->type) {
+       case FF_RUMBLE:
+               if (!test_bit(FF_PERIODIC, ff->ffbit))
+                       return -EINVAL;
+
+               /*
+                * calculate manginude of sine wave as average of rumble's
+                * 2/3 of strong magnitude and 1/3 of weak magnitude
+                */
+               magnitude = effect->u.rumble.strong_magnitude / 3 +
+                           effect->u.rumble.weak_magnitude / 6;
+
+               effect->type = FF_PERIODIC;
+               effect->u.periodic.waveform = FF_SINE;
+               effect->u.periodic.period = 50;
+               effect->u.periodic.magnitude = max(magnitude, 0x7fff);
+               effect->u.periodic.offset = 0;
+               effect->u.periodic.phase = 0;
+               effect->u.periodic.envelope.attack_length = 0;
+               effect->u.periodic.envelope.attack_level = 0;
+               effect->u.periodic.envelope.fade_length = 0;
+               effect->u.periodic.envelope.fade_level = 0;
+
+               return 0;
+
+       default:
+               /* Let driver handle conversion */
+               return 0;
+       }
+}
+
+/**
+ * input_ff_upload() - upload effect into force-feedback device
+ * @dev: input device
+ * @effect: effect to be uploaded
+ * @file: owner of the effect
+ */
+int input_ff_upload(struct input_dev *dev, struct ff_effect *effect,
+                   struct file *file)
+{
+       struct ff_device *ff = dev->ff;
+       struct ff_effect *old;
+       int ret = 0;
+       int id;
+
+       if (!test_bit(EV_FF, dev->evbit))
+               return -ENOSYS;
+
+       if (effect->type < FF_EFFECT_MIN || effect->type > FF_EFFECT_MAX ||
+           !test_bit(effect->type, dev->ffbit)) {
+               debug("invalid or not supported effect type in upload");
+               return -EINVAL;
+       }
+
+       if (effect->type == FF_PERIODIC &&
+           (effect->u.periodic.waveform < FF_WAVEFORM_MIN ||
+            effect->u.periodic.waveform > FF_WAVEFORM_MAX ||
+            !test_bit(effect->u.periodic.waveform, dev->ffbit))) {
+               debug("invalid or not supported wave form in upload");
+               return -EINVAL;
+       }
+
+       if (!test_bit(effect->type, ff->ffbit)) {
+               ret = compat_effect(ff, effect);
+               if (ret)
+                       return ret;
+       }
+
+       mutex_lock(&ff->mutex);
+
+       if (effect->id == -1) {
+               for (id = 0; id < ff->max_effects; id++)
+                    if (!ff->effect_owners[id])
+                       break;
+
+               if (id >= ff->max_effects) {
+                       ret = -ENOSPC;
+                       goto out;
+               }
+
+               effect->id = id;
+               old = NULL;
+
+       } else {
+               id = effect->id;
+
+               ret = check_effect_access(ff, id, file);
+               if (ret)
+                       goto out;
+
+               old = &ff->effects[id];
+
+               if (!check_effects_compatible(effect, old)) {
+                       ret = -EINVAL;
+                       goto out;
+               }
+       }
+
+       ret = ff->upload(dev, effect, old);
+       if (ret)
+               goto out;
+
+       ff->effects[id] = *effect;
+       ff->effect_owners[id] = file;
+
+ out:
+       mutex_unlock(&ff->mutex);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(input_ff_upload);
+
+/*
+ * Erases the effect if the requester is also the effect owner. The mutex
+ * should already be locked before calling this function.
+ */
+static int erase_effect(struct input_dev *dev, int effect_id,
+                       struct file *file)
+{
+       struct ff_device *ff = dev->ff;
+       int error;
+
+       error = check_effect_access(ff, effect_id, file);
+       if (error)
+               return error;
+
+       ff->playback(dev, effect_id, 0);
+
+       if (ff->erase) {
+               error = ff->erase(dev, effect_id);
+               if (error)
+                       return error;
+       }
+
+       ff->effect_owners[effect_id] = NULL;
+
+       return 0;
+}
+
+/**
+ * input_ff_erase - erase an effect from device
+ * @dev: input device to erase effect from
+ * @effect_id: id of the ffect to be erased
+ * @file: purported owner of the request
+ *
+ * This function erases a force-feedback effect from specified device.
+ * The effect will only be erased if it was uploaded through the same
+ * file handle that is requesting erase.
+ */
+int input_ff_erase(struct input_dev *dev, int effect_id, struct file *file)
+{
+       struct ff_device *ff = dev->ff;
+       int ret;
+
+       if (!test_bit(EV_FF, dev->evbit))
+               return -ENOSYS;
+
+       mutex_lock(&ff->mutex);
+       ret = erase_effect(dev, effect_id, file);
+       mutex_unlock(&ff->mutex);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(input_ff_erase);
+
+/*
+ * flush_effects - erase all effects owned by a file handle
+ */
+static int flush_effects(struct input_dev *dev, struct file *file)
+{
+       struct ff_device *ff = dev->ff;
+       int i;
+
+       debug("flushing now");
+
+       mutex_lock(&ff->mutex);
+
+       for (i = 0; i < ff->max_effects; i++)
+               erase_effect(dev, i, file);
+
+       mutex_unlock(&ff->mutex);
+
+       return 0;
+}
+
+/**
+ * input_ff_event() - generic handler for force-feedback events
+ * @dev: input device to send the effect to
+ * @type: event type (anything but EV_FF is ignored)
+ * @code: event code
+ * @value: event value
+ */
+int input_ff_event(struct input_dev *dev, unsigned int type,
+                  unsigned int code, int value)
+{
+       struct ff_device *ff = dev->ff;
+
+       if (type != EV_FF)
+               return 0;
+
+       mutex_lock(&ff->mutex);
+
+       switch (code) {
+       case FF_GAIN:
+               if (!test_bit(FF_GAIN, dev->ffbit) || value > 0xffff)
+                       break;
+
+               ff->set_gain(dev, value);
+               break;
+
+       case FF_AUTOCENTER:
+               if (!test_bit(FF_AUTOCENTER, dev->ffbit) || value > 0xffff)
+                       break;
+
+               ff->set_autocenter(dev, value);
+               break;
+
+       default:
+               ff->playback(dev, code, value);
+               break;
+       }
+
+       mutex_unlock(&ff->mutex);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(input_ff_event);
+
+/**
+ * input_ff_create() - create force-feedback device
+ * @dev: input device supporting force-feedback
+ * @max_effects: maximum number of effects supported by the device
+ *
+ * This function allocates all necessary memory for a force feedback
+ * portion of an input device and installs all default handlers.
+ * @dev->ffbit should be already set up before calling this function.
+ * Once ff device is created you need to setup its upload, erase,
+ * playback and other handlers before registering input device
+ */
+int input_ff_create(struct input_dev *dev, int max_effects)
+{
+       struct ff_device *ff;
+       int i;
+
+       if (!max_effects) {
+               printk(KERN_ERR
+                      "ff-core: cannot allocate device without any effects\n");
+               return -EINVAL;
+       }
+
+       ff = kzalloc(sizeof(struct ff_device) +
+                    max_effects * sizeof(struct file *), GFP_KERNEL);
+       if (!ff)
+               return -ENOMEM;
+
+       ff->effects = kcalloc(max_effects, sizeof(struct ff_effect),
+                             GFP_KERNEL);
+       if (!ff->effects) {
+               kfree(ff);
+               return -ENOMEM;
+       }
+
+       ff->max_effects = max_effects;
+       mutex_init(&ff->mutex);
+
+       dev->ff = ff;
+       dev->flush = flush_effects;
+       dev->event = input_ff_event;
+       set_bit(EV_FF, dev->evbit);
+
+       /* Copy "true" bits into ff device bitmap */
+       for (i = 0; i <= FF_MAX; i++)
+               if (test_bit(i, dev->ffbit))
+                       set_bit(i, ff->ffbit);
+
+       /* we can emulate RUMBLE with periodic effects */
+       if (test_bit(FF_PERIODIC, ff->ffbit))
+               set_bit(FF_RUMBLE, dev->ffbit);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(input_ff_create);
+
+/**
+ * input_ff_free() - frees force feedback portion of input device
+ * @dev: input device supporintg force feedback
+ *
+ * This function is only needed in error path as input core will
+ * automatically free force feedback structures when device is
+ * destroyed.
+ */
+void input_ff_destroy(struct input_dev *dev)
+{
+       clear_bit(EV_FF, dev->evbit);
+       if (dev->ff) {
+               if (dev->ff->destroy)
+                       dev->ff->destroy(dev->ff);
+               kfree(dev->ff->private);
+               kfree(dev->ff);
+               dev->ff = NULL;
+       }
+}
+EXPORT_SYMBOL_GPL(input_ff_destroy);
diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c
new file mode 100644 (file)
index 0000000..cd8b729
--- /dev/null
@@ -0,0 +1,515 @@
+/*
+ *  Force feedback support for memoryless devices
+ *
+ *  Copyright (c) 2006 Anssi Hannula <anssi.hannula@gmail.com>
+ *  Copyright (c) 2006 Dmitry Torokhov <dtor@mail.ru>
+ */
+
+/*
+ * 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
+ */
+
+/* #define DEBUG */
+
+#define debug(format, arg...) pr_debug("ff-memless: " format "\n", ## arg)
+
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+
+#include "fixp-arith.h"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Anssi Hannula <anssi.hannula@gmail.com>");
+MODULE_DESCRIPTION("Force feedback support for memoryless devices");
+
+/* Number of effects handled with memoryless devices */
+#define FF_MEMLESS_EFFECTS     16
+
+/* Envelope update interval in ms */
+#define FF_ENVELOPE_INTERVAL   50
+
+#define FF_EFFECT_STARTED      0
+#define FF_EFFECT_PLAYING      1
+#define FF_EFFECT_ABORTING     2
+
+struct ml_effect_state {
+       struct ff_effect *effect;
+       unsigned long flags;    /* effect state (STARTED, PLAYING, etc) */
+       int count;              /* loop count of the effect */
+       unsigned long play_at;  /* start time */
+       unsigned long stop_at;  /* stop time */
+       unsigned long adj_at;   /* last time the effect was sent */
+};
+
+struct ml_device {
+       void *private;
+       struct ml_effect_state states[FF_MEMLESS_EFFECTS];
+       int gain;
+       struct timer_list timer;
+       spinlock_t timer_lock;
+       struct input_dev *dev;
+
+       int (*play_effect)(struct input_dev *dev, void *data,
+                          struct ff_effect *effect);
+};
+
+static const struct ff_envelope *get_envelope(const struct ff_effect *effect)
+{
+       static const struct ff_envelope empty_envelope;
+
+       switch (effect->type) {
+               case FF_PERIODIC:
+                       return &effect->u.periodic.envelope;
+               case FF_CONSTANT:
+                       return &effect->u.constant.envelope;
+               default:
+                       return &empty_envelope;
+       }
+}
+
+/*
+ * Check for the next time envelope requires an update on memoryless devices
+ */
+static unsigned long calculate_next_time(struct ml_effect_state *state)
+{
+       const struct ff_envelope *envelope = get_envelope(state->effect);
+       unsigned long attack_stop, fade_start, next_fade;
+
+       if (envelope->attack_length) {
+               attack_stop = state->play_at +
+                       msecs_to_jiffies(envelope->attack_length);
+               if (time_before(state->adj_at, attack_stop))
+                       return state->adj_at +
+                                       msecs_to_jiffies(FF_ENVELOPE_INTERVAL);
+       }
+
+       if (state->effect->replay.length) {
+               if (envelope->fade_length) {
+                       /* check when fading should start */
+                       fade_start = state->stop_at -
+                                       msecs_to_jiffies(envelope->fade_length);
+
+                       if (time_before(state->adj_at, fade_start))
+                               return fade_start;
+
+                       /* already fading, advance to next checkpoint */
+                       next_fade = state->adj_at +
+                                       msecs_to_jiffies(FF_ENVELOPE_INTERVAL);
+                       if (time_before(next_fade, state->stop_at))
+                               return next_fade;
+               }
+
+               return state->stop_at;
+       }
+
+       return state->play_at;
+}
+
+static void ml_schedule_timer(struct ml_device *ml)
+{
+       struct ml_effect_state *state;
+       unsigned long now = jiffies;
+       unsigned long earliest = 0;
+       unsigned long next_at;
+       int events = 0;
+       int i;
+
+       debug("calculating next timer");
+
+       for (i = 0; i < FF_MEMLESS_EFFECTS; i++) {
+
+               state = &ml->states[i];
+
+               if (!test_bit(FF_EFFECT_STARTED, &state->flags))
+                       continue;
+
+               if (test_bit(FF_EFFECT_PLAYING, &state->flags))
+                       next_at = calculate_next_time(state);
+               else
+                       next_at = state->play_at;
+
+               if (time_before_eq(now, next_at) &&
+                   (++events == 1 || time_before(next_at, earliest)))
+                       earliest = next_at;
+       }
+
+       if (!events) {
+               debug("no actions");
+               del_timer(&ml->timer);
+       } else {
+               debug("timer set");
+               mod_timer(&ml->timer, earliest);
+       }
+}
+
+/*
+ * Apply an envelope to a value
+ */
+static int apply_envelope(struct ml_effect_state *state, int value,
+                         struct ff_envelope *envelope)
+{
+       struct ff_effect *effect = state->effect;
+       unsigned long now = jiffies;
+       int time_from_level;
+       int time_of_envelope;
+       int envelope_level;
+       int difference;
+
+       if (envelope->attack_length &&
+           time_before(now,
+                       state->play_at + msecs_to_jiffies(envelope->attack_length))) {
+               debug("value = 0x%x, attack_level = 0x%x", value,
+                     envelope->attack_level);
+               time_from_level = jiffies_to_msecs(now - state->play_at);
+               time_of_envelope = envelope->attack_length;
+               envelope_level = min_t(__s16, envelope->attack_level, 0x7fff);
+
+       } else if (envelope->fade_length && effect->replay.length &&
+                  time_after(now,
+                             state->stop_at - msecs_to_jiffies(envelope->fade_length)) &&
+                  time_before(now, state->stop_at)) {
+               time_from_level = jiffies_to_msecs(state->stop_at - now);
+               time_of_envelope = envelope->fade_length;
+               envelope_level = min_t(__s16, envelope->fade_level, 0x7fff);
+       } else
+               return value;
+
+       difference = abs(value) - envelope_level;
+
+       debug("difference = %d", difference);
+       debug("time_from_level = 0x%x", time_from_level);
+       debug("time_of_envelope = 0x%x", time_of_envelope);
+
+       difference = difference * time_from_level / time_of_envelope;
+
+       debug("difference = %d", difference);
+
+       return value < 0 ?
+               -(difference + envelope_level) : (difference + envelope_level);
+}
+
+/*
+ * Return the type the effect has to be converted into (memless devices)
+ */
+static int get_compatible_type(struct ff_device *ff, int effect_type)
+{
+
+       if (test_bit(effect_type, ff->ffbit))
+               return effect_type;
+
+       if (effect_type == FF_PERIODIC && test_bit(FF_RUMBLE, ff->ffbit))
+               return FF_RUMBLE;
+
+       printk(KERN_ERR
+              "ff-memless: invalid type in get_compatible_type()\n");
+
+       return 0;
+}
+
+/*
+ * Combine two effects and apply gain.
+ */
+static void ml_combine_effects(struct ff_effect *effect,
+                              struct ml_effect_state *state,
+                              int gain)
+{
+       struct ff_effect *new = state->effect;
+       unsigned int strong, weak, i;
+       int x, y;
+       fixp_t level;
+
+       switch (new->type) {
+       case FF_CONSTANT:
+               i = new->direction * 360 / 0xffff;
+               level = fixp_new16(apply_envelope(state,
+                                       new->u.constant.level,
+                                       &new->u.constant.envelope));
+               x = fixp_mult(fixp_sin(i), level) * gain / 0xffff;
+               y = fixp_mult(-fixp_cos(i), level) * gain / 0xffff;
+               /*
+                * here we abuse ff_ramp to hold x and y of constant force
+                * If in future any driver wants something else than x and y
+                * in s8, this should be changed to something more generic
+                */
+               effect->u.ramp.start_level =
+                       max(min(effect->u.ramp.start_level + x, 0x7f), -0x80);
+               effect->u.ramp.end_level =
+                       max(min(effect->u.ramp.end_level + y, 0x7f), -0x80);
+               break;
+
+       case FF_RUMBLE:
+               strong = new->u.rumble.strong_magnitude * gain / 0xffff;
+               weak = new->u.rumble.weak_magnitude * gain / 0xffff;
+               effect->u.rumble.strong_magnitude =
+                       min(strong + effect->u.rumble.strong_magnitude,
+                           0xffffU);
+               effect->u.rumble.weak_magnitude =
+                       min(weak + effect->u.rumble.weak_magnitude, 0xffffU);
+               break;
+
+       case FF_PERIODIC:
+               i = apply_envelope(state, abs(new->u.periodic.magnitude),
+                                  &new->u.periodic.envelope);
+
+               /* here we also scale it 0x7fff => 0xffff */
+               i = i * gain / 0x7fff;
+
+               effect->u.rumble.strong_magnitude =
+                       min(i + effect->u.rumble.strong_magnitude, 0xffffU);
+               effect->u.rumble.weak_magnitude =
+                       min(i + effect->u.rumble.weak_magnitude, 0xffffU);
+               break;
+
+       default:
+               printk(KERN_ERR "ff-memless: invalid type in ml_combine_effects()\n");
+               break;
+       }
+
+}
+
+
+/*
+ * Because memoryless devices have only one effect per effect type active
+ * at one time we have to combine multiple effects into one
+ */
+static int ml_get_combo_effect(struct ml_device *ml,
+                              unsigned long *effect_handled,
+                              struct ff_effect *combo_effect)
+{
+       struct ff_effect *effect;
+       struct ml_effect_state *state;
+       int effect_type;
+       int i;
+
+       memset(combo_effect, 0, sizeof(struct ff_effect));
+
+       for (i = 0; i < FF_MEMLESS_EFFECTS; i++) {
+               if (__test_and_set_bit(i, effect_handled))
+                       continue;
+
+               state = &ml->states[i];
+               effect = state->effect;
+
+               if (!test_bit(FF_EFFECT_STARTED, &state->flags))
+                       continue;
+
+               if (time_before(jiffies, state->play_at))
+                       continue;
+
+               /*
+                * here we have started effects that are either
+                * currently playing (and may need be aborted)
+                * or need to start playing.
+                */
+               effect_type = get_compatible_type(ml->dev->ff, effect->type);
+               if (combo_effect->type != effect_type) {
+                       if (combo_effect->type != 0) {
+                               __clear_bit(i, effect_handled);
+                               continue;
+                       }
+                       combo_effect->type = effect_type;
+               }
+
+               if (__test_and_clear_bit(FF_EFFECT_ABORTING, &state->flags)) {
+                       __clear_bit(FF_EFFECT_PLAYING, &state->flags);
+                       __clear_bit(FF_EFFECT_STARTED, &state->flags);
+               } else if (effect->replay.length &&
+                          time_after_eq(jiffies, state->stop_at)) {
+
+                       __clear_bit(FF_EFFECT_PLAYING, &state->flags);
+
+                       if (--state->count <= 0) {
+                               __clear_bit(FF_EFFECT_STARTED, &state->flags);
+                       } else {
+                               state->play_at = jiffies +
+                                       msecs_to_jiffies(effect->replay.delay);
+                               state->stop_at = state->play_at +
+                                       msecs_to_jiffies(effect->replay.length);
+                       }
+               } else {
+                       __set_bit(FF_EFFECT_PLAYING, &state->flags);
+                       state->adj_at = jiffies;
+                       ml_combine_effects(combo_effect, state, ml->gain);
+               }
+       }
+
+       return combo_effect->type != 0;
+}
+
+static void ml_play_effects(struct ml_device *ml)
+{
+       struct ff_effect effect;
+       DECLARE_BITMAP(handled_bm, FF_MEMLESS_EFFECTS);
+
+       memset(handled_bm, 0, sizeof(handled_bm));
+
+       while (ml_get_combo_effect(ml, handled_bm, &effect))
+               ml->play_effect(ml->dev, ml->private, &effect);
+
+       ml_schedule_timer(ml);
+}
+
+static void ml_effect_timer(unsigned long timer_data)
+{
+       struct input_dev *dev = (struct input_dev *)timer_data;
+       struct ml_device *ml = dev->ff->private;
+
+       debug("timer: updating effects");
+
+       spin_lock(&ml->timer_lock);
+       ml_play_effects(ml);
+       spin_unlock(&ml->timer_lock);
+}
+
+static void ml_ff_set_gain(struct input_dev *dev, u16 gain)
+{
+       struct ml_device *ml = dev->ff->private;
+       int i;
+
+       spin_lock_bh(&ml->timer_lock);
+
+       ml->gain = gain;
+
+       for (i = 0; i < FF_MEMLESS_EFFECTS; i++)
+               __clear_bit(FF_EFFECT_PLAYING, &ml->states[i].flags);
+
+       ml_play_effects(ml);
+
+       spin_unlock_bh(&ml->timer_lock);
+}
+
+static int ml_ff_playback(struct input_dev *dev, int effect_id, int value)
+{
+       struct ml_device *ml = dev->ff->private;
+       struct ml_effect_state *state = &ml->states[effect_id];
+
+       spin_lock_bh(&ml->timer_lock);
+
+       if (value > 0) {
+               debug("initiated play");
+
+               __set_bit(FF_EFFECT_STARTED, &state->flags);
+               state->count = value;
+               state->play_at = jiffies +
+                                msecs_to_jiffies(state->effect->replay.delay);
+               state->stop_at = state->play_at +
+                                msecs_to_jiffies(state->effect->replay.length);
+               state->adj_at = state->play_at;
+
+               ml_schedule_timer(ml);
+
+       } else {
+               debug("initiated stop");
+
+               if (test_bit(FF_EFFECT_PLAYING, &state->flags))
+                       __set_bit(FF_EFFECT_ABORTING, &state->flags);
+               else
+                       __clear_bit(FF_EFFECT_STARTED, &state->flags);
+
+               ml_play_effects(ml);
+       }
+
+       spin_unlock_bh(&ml->timer_lock);
+
+       return 0;
+}
+
+static int ml_ff_upload(struct input_dev *dev,
+                       struct ff_effect *effect, struct ff_effect *old)
+{
+       struct ml_device *ml = dev->ff->private;
+       struct ml_effect_state *state = &ml->states[effect->id];
+
+       spin_lock_bh(&ml->timer_lock);
+
+       if (test_bit(FF_EFFECT_STARTED, &state->flags)) {
+               __clear_bit(FF_EFFECT_PLAYING, &state->flags);
+               state->play_at = jiffies +
+                                msecs_to_jiffies(state->effect->replay.delay);
+               state->stop_at = state->play_at +
+                                msecs_to_jiffies(state->effect->replay.length);
+               state->adj_at = state->play_at;
+               ml_schedule_timer(ml);
+       }
+
+       spin_unlock_bh(&ml->timer_lock);
+
+       return 0;
+}
+
+static void ml_ff_destroy(struct ff_device *ff)
+{
+       struct ml_device *ml = ff->private;
+
+       kfree(ml->private);
+}
+
+/**
+ * input_ff_create_memless() - create memoryless FF device
+ * @dev: input device supporting force-feedback
+ * @data: driver-specific data to be passed into @play_effect
+ * @play_effect: driver-specific method for playing FF effect
+ */
+int input_ff_create_memless(struct input_dev *dev, void *data,
+               int (*play_effect)(struct input_dev *, void *, struct ff_effect *))
+{
+       struct ml_device *ml;
+       struct ff_device *ff;
+       int error;
+       int i;
+
+       ml = kzalloc(sizeof(struct ml_device), GFP_KERNEL);
+       if (!ml)
+               return -ENOMEM;
+
+       ml->dev = dev;
+       ml->private = data;
+       ml->play_effect = play_effect;
+       ml->gain = 0xffff;
+       spin_lock_init(&ml->timer_lock);
+       setup_timer(&ml->timer, ml_effect_timer, (unsigned long)dev);
+
+       set_bit(FF_GAIN, dev->ffbit);
+
+       error = input_ff_create(dev, FF_MEMLESS_EFFECTS);
+       if (error) {
+               kfree(ml);
+               return error;
+       }
+
+       ff = dev->ff;
+       ff->private = ml;
+       ff->upload = ml_ff_upload;
+       ff->playback = ml_ff_playback;
+       ff->set_gain = ml_ff_set_gain;
+       ff->destroy = ml_ff_destroy;
+
+       /* we can emulate periodic effects with RUMBLE */
+       if (test_bit(FF_RUMBLE, ff->ffbit)) {
+               set_bit(FF_PERIODIC, dev->ffbit);
+               set_bit(FF_SINE, dev->ffbit);
+               set_bit(FF_TRIANGLE, dev->ffbit);
+               set_bit(FF_SQUARE, dev->ffbit);
+       }
+
+       for (i = 0; i < FF_MEMLESS_EFFECTS; i++)
+               ml->states[i].effect = &ff->effects[i];
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(input_ff_create_memless);
index 9cb4b9a54f01ffa38dd0f803785f190dae1f8adb..1c8c8a5bc4a91c0076c9af4539ef3a768102afed 100644 (file)
@@ -176,6 +176,10 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
                        break;
 
                case EV_FF:
+
+                       if (value < 0)
+                               return;
+
                        if (dev->event)
                                dev->event(dev, type, code, value);
                        break;
@@ -309,7 +313,8 @@ static void input_link_handle(struct input_handle *handle)
                if (i != NBITS(max)) \
                        continue;
 
-static struct input_device_id *input_match_device(struct input_device_id *id, struct input_dev *dev)
+static const struct input_device_id *input_match_device(const struct input_device_id *id,
+                                                       struct input_dev *dev)
 {
        int i;
 
@@ -762,7 +767,9 @@ static void input_dev_release(struct class_device *class_dev)
 {
        struct input_dev *dev = to_input_dev(class_dev);
 
+       input_ff_destroy(dev);
        kfree(dev);
+
        module_put(THIS_MODULE);
 }
 
@@ -899,12 +906,13 @@ struct input_dev *input_allocate_device(void)
 
        dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);
        if (dev) {
-               dev->dynalloc = 1;
                dev->cdev.class = &input_class;
                class_device_initialize(&dev->cdev);
                mutex_init(&dev->mutex);
                INIT_LIST_HEAD(&dev->h_list);
                INIT_LIST_HEAD(&dev->node);
+
+               __module_get(THIS_MODULE);
        }
 
        return dev;
@@ -929,17 +937,10 @@ int input_register_device(struct input_dev *dev)
        static atomic_t input_no = ATOMIC_INIT(0);
        struct input_handle *handle;
        struct input_handler *handler;
-       struct input_device_id *id;
+       const struct input_device_id *id;
        const char *path;
        int error;
 
-       if (!dev->dynalloc) {
-               printk(KERN_WARNING "input: device %s is statically allocated, will not register\n"
-                       "Please convert to input_allocate_device() or contact dtor_core@ameritech.net\n",
-                       dev->name ? dev->name : "<Unknown>");
-               return -EINVAL;
-       }
-
        set_bit(EV_SYN, dev->evbit);
 
        /*
@@ -955,10 +956,8 @@ int input_register_device(struct input_dev *dev)
                dev->rep[REP_PERIOD] = 33;
        }
 
-       INIT_LIST_HEAD(&dev->h_list);
        list_add_tail(&dev->node, &input_dev_list);
 
-       dev->cdev.class = &input_class;
        snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id),
                 "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);
 
@@ -978,8 +977,6 @@ int input_register_device(struct input_dev *dev)
        if (error)
                goto fail3;
 
-       __module_get(THIS_MODULE);
-
        path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL);
        printk(KERN_INFO "input: %s as %s\n",
                dev->name ? dev->name : "Unspecified device", path ? path : "N/A");
@@ -1008,9 +1005,12 @@ EXPORT_SYMBOL(input_register_device);
 void input_unregister_device(struct input_dev *dev)
 {
        struct list_head *node, *next;
+       int code;
 
-       if (!dev)
-               return;
+       for (code = 0; code <= KEY_MAX; code++)
+               if (test_bit(code, dev->key))
+                       input_report_key(dev, code, 0);
+       input_sync(dev);
 
        del_timer_sync(&dev->timer);
 
@@ -1037,19 +1037,20 @@ void input_unregister_device(struct input_dev *dev)
 }
 EXPORT_SYMBOL(input_unregister_device);
 
-void input_register_handler(struct input_handler *handler)
+int input_register_handler(struct input_handler *handler)
 {
        struct input_dev *dev;
        struct input_handle *handle;
-       struct input_device_id *id;
-
-       if (!handler)
-               return;
+       const struct input_device_id *id;
 
        INIT_LIST_HEAD(&handler->h_list);
 
-       if (handler->fops != NULL)
+       if (handler->fops != NULL) {
+               if (input_table[handler->minor >> 5])
+                       return -EBUSY;
+
                input_table[handler->minor >> 5] = handler;
+       }
 
        list_add_tail(&handler->node, &input_handler_list);
 
@@ -1063,6 +1064,7 @@ void input_register_handler(struct input_handler *handler)
                                }
 
        input_wakeup_procfs_readers();
+       return 0;
 }
 EXPORT_SYMBOL(input_register_handler);
 
index d67157513bf7dc286024e182400b545bf895d0c6..9f3529ad3fdab5b149cf7c835fc32e413e6c5109 100644 (file)
@@ -451,7 +451,7 @@ static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
        }
 }
 
-static struct file_operations joydev_fops = {
+static const struct file_operations joydev_fops = {
        .owner =        THIS_MODULE,
        .read =         joydev_read,
        .write =        joydev_write,
@@ -465,7 +465,8 @@ static struct file_operations joydev_fops = {
        .fasync =       joydev_fasync,
 };
 
-static struct input_handle *joydev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
+static struct input_handle *joydev_connect(struct input_handler *handler, struct input_dev *dev,
+                                          const struct input_device_id *id)
 {
        struct joydev *joydev;
        struct class_device *cdev;
@@ -562,7 +563,7 @@ static void joydev_disconnect(struct input_handle *handle)
                joydev_free(joydev);
 }
 
-static struct input_device_id joydev_blacklist[] = {
+static const struct input_device_id joydev_blacklist[] = {
        {
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
                .evbit = { BIT(EV_KEY) },
@@ -571,7 +572,7 @@ static struct input_device_id joydev_blacklist[] = {
        { }     /* Terminating entry */
 };
 
-static struct input_device_id joydev_ids[] = {
+static const struct input_device_id joydev_ids[] = {
        {
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
                .evbit = { BIT(EV_ABS) },
@@ -605,8 +606,7 @@ static struct input_handler joydev_handler = {
 
 static int __init joydev_init(void)
 {
-       input_register_handler(&joydev_handler);
-       return 0;
+       return input_register_handler(&joydev_handler);
 }
 
 static void __exit joydev_exit(void)
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 50c90765aee15274eefc8b8fd05367af14e00462..8fb0c19cc60e27b459f084e59075aea46735ca02 100644 (file)
@@ -165,19 +165,19 @@ static int make_condition_modifier(struct iforce* iforce,
        data[0] = LO(mod_chunk->start);
        data[1] = HI(mod_chunk->start);
 
-       data[2] = (100*rk)>>15; /* Dangerous: the sign is extended by gcc on plateforms providing an arith shift */
-       data[3] = (100*lk)>>15; /* This code is incorrect on cpus lacking arith shift */
+       data[2] = (100 * rk) >> 15;     /* Dangerous: the sign is extended by gcc on plateforms providing an arith shift */
+       data[3] = (100 * lk) >> 15; /* This code is incorrect on cpus lacking arith shift */
 
-       center = (500*center)>>15;
+       center = (500 * center) >> 15;
        data[4] = LO(center);
        data[5] = HI(center);
 
-       db = (1000*db)>>16;
+       db = (1000 * db) >> 16;
        data[6] = LO(db);
        data[7] = HI(db);
 
-       data[8] = (100*rsat)>>16;
-       data[9] = (100*lsat)>>16;
+       data[8] = (100 * rsat) >> 16;
+       data[9] = (100 * lsat) >> 16;
 
        iforce_send_packet(iforce, FF_CMD_CONDITION, data);
        iforce_dump_packet("condition", FF_CMD_CONDITION, data);
@@ -188,6 +188,7 @@ static int make_condition_modifier(struct iforce* iforce,
 static unsigned char find_button(struct iforce *iforce, signed short button)
 {
        int i;
+
        for (i = 1; iforce->type->btn[i] >= 0; i++)
                if (iforce->type->btn[i] == button)
                        return i + 1;
@@ -198,19 +199,17 @@ static unsigned char find_button(struct iforce *iforce, signed short button)
  * Analyse the changes in an effect, and tell if we need to send an condition
  * parameter packet
  */
-static int need_condition_modifier(struct iforce* iforce, struct ff_effect* new)
+static int need_condition_modifier(struct ff_effect *old, struct ff_effect *new)
 {
-       int id = new->id;
-       struct ff_effect* old = &iforce->core_effects[id].effect;
-       int ret=0;
+       int ret = 0;
        int i;
 
        if (new->type != FF_SPRING && new->type != FF_FRICTION) {
                printk(KERN_WARNING "iforce.c: bad effect type in need_condition_modifier\n");
-               return FALSE;
+               return 0;
        }
 
-       for(i=0; i<2; i++) {
+       for (i = 0; i < 2; i++) {
                ret |= old->u.condition[i].right_saturation != new->u.condition[i].right_saturation
                        || old->u.condition[i].left_saturation != new->u.condition[i].left_saturation
                        || old->u.condition[i].right_coeff != new->u.condition[i].right_coeff
@@ -225,35 +224,29 @@ static int need_condition_modifier(struct iforce* iforce, struct ff_effect* new)
  * Analyse the changes in an effect, and tell if we need to send a magnitude
  * parameter packet
  */
-static int need_magnitude_modifier(struct iforce* iforce, struct ff_effect* effect)
+static int need_magnitude_modifier(struct ff_effect *old, struct ff_effect *effect)
 {
-       int id = effect->id;
-       struct ff_effect* old = &iforce->core_effects[id].effect;
-
        if (effect->type != FF_CONSTANT) {
                printk(KERN_WARNING "iforce.c: bad effect type in need_envelope_modifier\n");
-               return FALSE;
+               return 0;
        }
 
-       return (old->u.constant.level != effect->u.constant.level);
+       return old->u.constant.level != effect->u.constant.level;
 }
 
 /*
  * Analyse the changes in an effect, and tell if we need to send an envelope
  * parameter packet
  */
-static int need_envelope_modifier(struct iforce* iforce, struct ff_effect* effect)
+static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effect)
 {
-       int id = effect->id;
-       struct ff_effect* old = &iforce->core_effects[id].effect;
-
        switch (effect->type) {
        case FF_CONSTANT:
                if (old->u.constant.envelope.attack_length != effect->u.constant.envelope.attack_length
                || old->u.constant.envelope.attack_level != effect->u.constant.envelope.attack_level
                || old->u.constant.envelope.fade_length != effect->u.constant.envelope.fade_length
                || old->u.constant.envelope.fade_level != effect->u.constant.envelope.fade_level)
-                       return TRUE;
+                       return 1;
                break;
 
        case FF_PERIODIC:
@@ -261,30 +254,26 @@ static int need_envelope_modifier(struct iforce* iforce, struct ff_effect* effec
                || old->u.periodic.envelope.attack_level != effect->u.periodic.envelope.attack_level
                || old->u.periodic.envelope.fade_length != effect->u.periodic.envelope.fade_length
                || old->u.periodic.envelope.fade_level != effect->u.periodic.envelope.fade_level)
-                       return TRUE;
+                       return 1;
                break;
 
        default:
                printk(KERN_WARNING "iforce.c: bad effect type in need_envelope_modifier\n");
        }
 
-       return FALSE;
+       return 0;
 }
 
 /*
  * Analyse the changes in an effect, and tell if we need to send a periodic
  * parameter effect
  */
-static int need_period_modifier(struct iforce* iforce, struct ff_effect* new)
+static int need_period_modifier(struct ff_effect *old, struct ff_effect *new)
 {
-       int id = new->id;
-       struct ff_effect* old = &iforce->core_effects[id].effect;
-
        if (new->type != FF_PERIODIC) {
-               printk(KERN_WARNING "iforce.c: bad effect type in need_periodic_modifier\n");
-               return FALSE;
+               printk(KERN_WARNING "iforce.c: bad effect type in need_period_modifier\n");
+               return 0;
        }
-
        return (old->u.periodic.period != new->u.periodic.period
                || old->u.periodic.magnitude != new->u.periodic.magnitude
                || old->u.periodic.offset != new->u.periodic.offset
@@ -295,19 +284,16 @@ static int need_period_modifier(struct iforce* iforce, struct ff_effect* new)
  * Analyse the changes in an effect, and tell if we need to send an effect
  * packet
  */
-static int need_core(struct iforce* iforce, struct ff_effect* new)
+static int need_core(struct ff_effect *old, struct ff_effect *new)
 {
-       int id = new->id;
-       struct ff_effect* old = &iforce->core_effects[id].effect;
-
        if (old->direction != new->direction
                || old->trigger.button != new->trigger.button
                || old->trigger.interval != new->trigger.interval
                || old->replay.length != new->replay.length
                || old->replay.delay != new->replay.delay)
-               return TRUE;
+               return 1;
 
-       return FALSE;
+       return 0;
 }
 /*
  * Send the part common to all effects to the device
@@ -360,7 +346,7 @@ static int make_core(struct iforce* iforce, u16 id, u16 mod_id1, u16 mod_id2,
  * Upload a periodic effect to the device
  * See also iforce_upload_constant.
  */
-int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effect, int is_update)
+int iforce_upload_periodic(struct iforce *iforce, struct ff_effect *effect, struct ff_effect *old)
 {
        u8 wave_code;
        int core_id = effect->id;
@@ -371,23 +357,25 @@ int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effect, int
        int param2_err = 1;
        int core_err = 0;
 
-       if (!is_update || need_period_modifier(iforce, effect)) {
+       if (!old || need_period_modifier(old, effect)) {
                param1_err = make_period_modifier(iforce, mod1_chunk,
-                       is_update,
+                       old != NULL,
                        effect->u.periodic.magnitude, effect->u.periodic.offset,
                        effect->u.periodic.period, effect->u.periodic.phase);
-               if (param1_err) return param1_err;
+               if (param1_err)
+                       return param1_err;
                set_bit(FF_MOD1_IS_USED, core_effect->flags);
        }
 
-       if (!is_update || need_envelope_modifier(iforce, effect)) {
+       if (!old || need_envelope_modifier(old, effect)) {
                param2_err = make_envelope_modifier(iforce, mod2_chunk,
-                       is_update,
+                       old !=NULL,
                        effect->u.periodic.envelope.attack_length,
                        effect->u.periodic.envelope.attack_level,
                        effect->u.periodic.envelope.fade_length,
                        effect->u.periodic.envelope.fade_level);
-               if (param2_err) return param2_err;
+               if (param2_err)
+                       return param2_err;
                set_bit(FF_MOD2_IS_USED, core_effect->flags);
        }
 
@@ -400,7 +388,7 @@ int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effect, int
                default:                wave_code = 0x20; break;
        }
 
-       if (!is_update || need_core(iforce, effect)) {
+       if (!old || need_core(old, effect)) {
                core_err = make_core(iforce, effect->id,
                        mod1_chunk->start,
                        mod2_chunk->start,
@@ -429,7 +417,7 @@ int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effect, int
  *  0 Ok, effect created or updated
  *  1 effect did not change since last upload, and no packet was therefore sent
  */
-int iforce_upload_constant(struct iforce* iforce, struct ff_effect* effect, int is_update)
+int iforce_upload_constant(struct iforce *iforce, struct ff_effect *effect, struct ff_effect *old)
 {
        int core_id = effect->id;
        struct iforce_core_effect* core_effect = iforce->core_effects + core_id;
@@ -439,26 +427,28 @@ int iforce_upload_constant(struct iforce* iforce, struct ff_effect* effect, int
        int param2_err = 1;
        int core_err = 0;
 
-       if (!is_update || need_magnitude_modifier(iforce, effect)) {
+       if (!old || need_magnitude_modifier(old, effect)) {
                param1_err = make_magnitude_modifier(iforce, mod1_chunk,
-                       is_update,
+                       old != NULL,
                        effect->u.constant.level);
-               if (param1_err) return param1_err;
+               if (param1_err)
+                       return param1_err;
                set_bit(FF_MOD1_IS_USED, core_effect->flags);
        }
 
-       if (!is_update || need_envelope_modifier(iforce, effect)) {
+       if (!old || need_envelope_modifier(old, effect)) {
                param2_err = make_envelope_modifier(iforce, mod2_chunk,
-                       is_update,
+                       old != NULL,
                        effect->u.constant.envelope.attack_length,
                        effect->u.constant.envelope.attack_level,
                        effect->u.constant.envelope.fade_length,
                        effect->u.constant.envelope.fade_level);
-               if (param2_err) return param2_err;
+               if (param2_err)
+                       return param2_err;
                set_bit(FF_MOD2_IS_USED, core_effect->flags);
        }
 
-       if (!is_update || need_core(iforce, effect)) {
+       if (!old || need_core(old, effect)) {
                core_err = make_core(iforce, effect->id,
                        mod1_chunk->start,
                        mod2_chunk->start,
@@ -483,7 +473,7 @@ int iforce_upload_constant(struct iforce* iforce, struct ff_effect* effect, int
 /*
  * Upload an condition effect. Those are for example friction, inertia, springs...
  */
-int iforce_upload_condition(struct iforce* iforce, struct ff_effect* effect, int is_update)
+int iforce_upload_condition(struct iforce *iforce, struct ff_effect *effect, struct ff_effect *old)
 {
        int core_id = effect->id;
        struct iforce_core_effect* core_effect = iforce->core_effects + core_id;
@@ -494,37 +484,39 @@ int iforce_upload_condition(struct iforce* iforce, struct ff_effect* effect, int
        int core_err = 0;
 
        switch (effect->type) {
-               case FF_SPRING:         type = 0x40; break;
-               case FF_DAMPER:         type = 0x41; break;
+               case FF_SPRING: type = 0x40; break;
+               case FF_DAMPER: type = 0x41; break;
                default: return -1;
        }
 
-       if (!is_update || need_condition_modifier(iforce, effect)) {
+       if (!old || need_condition_modifier(old, effect)) {
                param_err = make_condition_modifier(iforce, mod1_chunk,
-                       is_update,
+                       old != NULL,
                        effect->u.condition[0].right_saturation,
                        effect->u.condition[0].left_saturation,
                        effect->u.condition[0].right_coeff,
                        effect->u.condition[0].left_coeff,
                        effect->u.condition[0].deadband,
                        effect->u.condition[0].center);
-               if (param_err) return param_err;
+               if (param_err)
+                       return param_err;
                set_bit(FF_MOD1_IS_USED, core_effect->flags);
 
                param_err = make_condition_modifier(iforce, mod2_chunk,
-                       is_update,
+                       old != NULL,
                        effect->u.condition[1].right_saturation,
                        effect->u.condition[1].left_saturation,
                        effect->u.condition[1].right_coeff,
                        effect->u.condition[1].left_coeff,
                        effect->u.condition[1].deadband,
                        effect->u.condition[1].center);
-               if (param_err) return param_err;
+               if (param_err)
+                       return param_err;
                set_bit(FF_MOD2_IS_USED, core_effect->flags);
 
        }
 
-       if (!is_update || need_core(iforce, effect)) {
+       if (!old || need_core(old, effect)) {
                core_err = make_core(iforce, effect->id,
                        mod1_chunk->start, mod2_chunk->start,
                        type, 0xc0,
index b4914e7231f863a3073da1c7e8e320e3e93c9c87..24c684bc63375917e44a06b3eae67947a501497d 100644 (file)
@@ -83,103 +83,57 @@ static struct iforce_device iforce_device[] = {
        { 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]",         btn_joystick, abs_joystick, ff_iforce }
 };
 
-
-
-static int iforce_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
+static int iforce_playback(struct input_dev *dev, int effect_id, int value)
 {
        struct iforce* iforce = dev->private;
-       unsigned char data[3];
-
-       if (type != EV_FF)
-               return -1;
-
-       switch (code) {
-
-               case FF_GAIN:
-
-                       data[0] = value >> 9;
-                       iforce_send_packet(iforce, FF_CMD_GAIN, data);
-
-                       return 0;
-
-               case FF_AUTOCENTER:
+       struct iforce_core_effect *core_effect = &iforce->core_effects[effect_id];
 
-                       data[0] = 0x03;
-                       data[1] = value >> 9;
-                       iforce_send_packet(iforce, FF_CMD_AUTOCENTER, data);
+       if (value > 0)
+               set_bit(FF_CORE_SHOULD_PLAY, core_effect->flags);
+       else
+               clear_bit(FF_CORE_SHOULD_PLAY, core_effect->flags);
 
-                       data[0] = 0x04;
-                       data[1] = 0x01;
-                       iforce_send_packet(iforce, FF_CMD_AUTOCENTER, data);
+       iforce_control_playback(iforce, effect_id, value);
+       return 0;
+}
 
-                       return 0;
+static void iforce_set_gain(struct input_dev *dev, u16 gain)
+{
+       struct iforce* iforce = dev->private;
+       unsigned char data[3];
 
-               default: /* Play or stop an effect */
+       data[0] = gain >> 9;
+       iforce_send_packet(iforce, FF_CMD_GAIN, data);
+}
 
-                       if (!CHECK_OWNERSHIP(code, iforce)) {
-                               return -1;
-                       }
-                       if (value > 0) {
-                               set_bit(FF_CORE_SHOULD_PLAY, iforce->core_effects[code].flags);
-                       }
-                       else {
-                               clear_bit(FF_CORE_SHOULD_PLAY, iforce->core_effects[code].flags);
-                       }
+static void iforce_set_autocenter(struct input_dev *dev, u16 magnitude)
+{
+       struct iforce* iforce = dev->private;
+       unsigned char data[3];
 
-                       iforce_control_playback(iforce, code, value);
-                       return 0;
-       }
+       data[0] = 0x03;
+       data[1] = magnitude >> 9;
+       iforce_send_packet(iforce, FF_CMD_AUTOCENTER, data);
 
-       return -1;
+       data[0] = 0x04;
+       data[1] = 0x01;
+       iforce_send_packet(iforce, FF_CMD_AUTOCENTER, data);
 }
 
 /*
  * Function called when an ioctl is performed on the event dev entry.
  * It uploads an effect to the device
  */
-static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect)
+static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect, struct ff_effect *old)
 {
        struct iforce* iforce = dev->private;
-       int id;
+       struct iforce_core_effect *core_effect = &iforce->core_effects[effect->id];
        int ret;
-       int is_update;
-
-/* Check this effect type is supported by this device */
-       if (!test_bit(effect->type, iforce->dev->ffbit))
-               return -EINVAL;
-
-/*
- * If we want to create a new effect, get a free id
- */
-       if (effect->id == -1) {
-
-               for (id = 0; id < FF_EFFECTS_MAX; ++id)
-                       if (!test_and_set_bit(FF_CORE_IS_USED, iforce->core_effects[id].flags))
-                               break;
-
-               if (id == FF_EFFECTS_MAX || id >= iforce->dev->ff_effects_max)
-                       return -ENOMEM;
-
-               effect->id = id;
-               iforce->core_effects[id].owner = current->pid;
-               iforce->core_effects[id].flags[0] = (1 << FF_CORE_IS_USED);     /* Only IS_USED bit must be set */
-
-               is_update = FALSE;
-       }
-       else {
-               /* We want to update an effect */
-               if (!CHECK_OWNERSHIP(effect->id, iforce))
-                       return -EACCES;
-
-               /* Parameter type cannot be updated */
-               if (effect->type != iforce->core_effects[effect->id].effect.type)
-                       return -EINVAL;
 
+       if (__test_and_set_bit(FF_CORE_IS_USED, core_effect->flags)) {
                /* Check the effect is not already being updated */
-               if (test_bit(FF_CORE_UPDATE, iforce->core_effects[effect->id].flags))
+               if (test_bit(FF_CORE_UPDATE, core_effect->flags))
                        return -EAGAIN;
-
-               is_update = TRUE;
        }
 
 /*
@@ -188,28 +142,28 @@ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect)
        switch (effect->type) {
 
                case FF_PERIODIC:
-                       ret = iforce_upload_periodic(iforce, effect, is_update);
+                       ret = iforce_upload_periodic(iforce, effect, old);
                        break;
 
                case FF_CONSTANT:
-                       ret = iforce_upload_constant(iforce, effect, is_update);
+                       ret = iforce_upload_constant(iforce, effect, old);
                        break;
 
                case FF_SPRING:
                case FF_DAMPER:
-                       ret = iforce_upload_condition(iforce, effect, is_update);
+                       ret = iforce_upload_condition(iforce, effect, old);
                        break;
 
                default:
                        return -EINVAL;
        }
+
        if (ret == 0) {
                /* A packet was sent, forbid new updates until we are notified
                 * that the packet was updated
                 */
-               set_bit(FF_CORE_UPDATE, iforce->core_effects[effect->id].flags);
+               set_bit(FF_CORE_UPDATE, core_effect->flags);
        }
-       iforce->core_effects[effect->id].effect = *effect;
        return ret;
 }
 
@@ -219,20 +173,9 @@ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect)
  */
 static int iforce_erase_effect(struct input_dev *dev, int effect_id)
 {
-       struct iforce* iforce = dev->private;
+       struct iforce *iforce = dev->private;
+       struct iforce_core_effect *core_effect = &iforce->core_effects[effect_id];
        int err = 0;
-       struct iforce_core_effect* core_effect;
-
-       if (effect_id < 0 || effect_id >= FF_EFFECTS_MAX)
-               return -EINVAL;
-
-       core_effect = &iforce->core_effects[effect_id];
-
-       /* Check who is trying to erase this effect */
-       if (core_effect->owner != current->pid) {
-               printk(KERN_WARNING "iforce-main.c: %d tried to erase an effect belonging to %d\n", current->pid, core_effect->owner);
-               return -EACCES;
-       }
 
        if (test_bit(FF_MOD1_IS_USED, core_effect->flags))
                err = release_resource(&core_effect->mod1_chunk);
@@ -240,7 +183,7 @@ static int iforce_erase_effect(struct input_dev *dev, int effect_id)
        if (!err && test_bit(FF_MOD2_IS_USED, core_effect->flags))
                err = release_resource(&core_effect->mod2_chunk);
 
-       /*TODO: remember to change that if more FF_MOD* bits are added */
+       /* TODO: remember to change that if more FF_MOD* bits are added */
        core_effect->flags[0] = 0;
 
        return err;
@@ -260,52 +203,31 @@ static int iforce_open(struct input_dev *dev)
 #endif
        }
 
-       /* Enable force feedback */
-       iforce_send_packet(iforce, FF_CMD_ENABLE, "\004");
+       if (test_bit(EV_FF, dev->evbit)) {
+               /* Enable force feedback */
+               iforce_send_packet(iforce, FF_CMD_ENABLE, "\004");
+       }
 
        return 0;
 }
 
-static int iforce_flush(struct input_dev *dev, struct file *file)
+static void iforce_release(struct input_dev *dev)
 {
        struct iforce *iforce = dev->private;
        int i;
 
-       /* Erase all effects this process owns */
-       for (i=0; i<dev->ff_effects_max; ++i) {
-
-               if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags) &&
-                       current->pid == iforce->core_effects[i].owner) {
-
-                       /* Stop effect */
-                       input_report_ff(dev, i, 0);
-
-                       /* Free ressources assigned to effect */
-                       if (iforce_erase_effect(dev, i)) {
-                               printk(KERN_WARNING "iforce_flush: erase effect %d failed\n", i);
+       if (test_bit(EV_FF, dev->evbit)) {
+               /* Check: no effects should be present in memory */
+               for (i = 0; i < dev->ff->max_effects; i++) {
+                       if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags)) {
+                               printk(KERN_WARNING "iforce_release: Device still owns effects\n");
+                               break;
                        }
                }
 
+               /* Disable force feedback playback */
+               iforce_send_packet(iforce, FF_CMD_ENABLE, "\001");
        }
-       return 0;
-}
-
-static void iforce_release(struct input_dev *dev)
-{
-       struct iforce *iforce = dev->private;
-       int i;
-
-       /* Check: no effect should be present in memory */
-       for (i=0; i<dev->ff_effects_max; ++i) {
-               if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags))
-                       break;
-       }
-       if (i<dev->ff_effects_max) {
-               printk(KERN_WARNING "iforce_release: Device still owns effects\n");
-       }
-
-       /* Disable force feedback playback */
-       iforce_send_packet(iforce, FF_CMD_ENABLE, "\001");
 
        switch (iforce->bus) {
 #ifdef CONFIG_JOYSTICK_IFORCE_USB
@@ -342,8 +264,10 @@ void iforce_delete_device(struct iforce *iforce)
 int iforce_init_device(struct iforce *iforce)
 {
        struct input_dev *input_dev;
+       struct ff_device *ff;
        unsigned char c[] = "CEOV";
-       int i;
+       int i, error;
+       int ff_effects = 0;
 
        input_dev = input_allocate_device();
        if (!input_dev)
@@ -378,11 +302,6 @@ int iforce_init_device(struct iforce *iforce)
        input_dev->name = "Unknown I-Force device";
        input_dev->open = iforce_open;
        input_dev->close = iforce_release;
-       input_dev->flush = iforce_flush;
-       input_dev->event = iforce_input_event;
-       input_dev->upload_effect = iforce_upload_effect;
-       input_dev->erase_effect = iforce_erase_effect;
-       input_dev->ff_effects_max = 10;
 
 /*
  * On-device memory allocation.
@@ -430,15 +349,15 @@ int iforce_init_device(struct iforce *iforce)
                printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet B\n");
 
        if (!iforce_get_id_packet(iforce, "N"))
-               iforce->dev->ff_effects_max = iforce->edata[1];
+               ff_effects = iforce->edata[1];
        else
                printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet N\n");
 
        /* Check if the device can store more effects than the driver can really handle */
-       if (iforce->dev->ff_effects_max > FF_EFFECTS_MAX) {
-               printk(KERN_WARNING "input??: Device can handle %d effects, but N_EFFECTS_MAX is set to %d in iforce.h\n",
-                       iforce->dev->ff_effects_max, FF_EFFECTS_MAX);
-               iforce->dev->ff_effects_max = FF_EFFECTS_MAX;
+       if (ff_effects > IFORCE_EFFECTS_MAX) {
+               printk(KERN_WARNING "iforce: Limiting number of effects to %d (device reports %d)\n",
+                      IFORCE_EFFECTS_MAX, ff_effects);
+               ff_effects = IFORCE_EFFECTS_MAX;
        }
 
 /*
@@ -472,12 +391,10 @@ int iforce_init_device(struct iforce *iforce)
  * Set input device bitfields and ranges.
  */
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF) | BIT(EV_FF_STATUS);
+       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF_STATUS);
 
-       for (i = 0; iforce->type->btn[i] >= 0; i++) {
-               signed short t = iforce->type->btn[i];
-               set_bit(t, input_dev->keybit);
-       }
+       for (i = 0; iforce->type->btn[i] >= 0; i++)
+               set_bit(iforce->type->btn[i], input_dev->keybit);
        set_bit(BTN_DEAD, input_dev->keybit);
 
        for (i = 0; iforce->type->abs[i] >= 0; i++) {
@@ -516,9 +433,24 @@ int iforce_init_device(struct iforce *iforce)
                }
        }
 
-       for (i = 0; iforce->type->ff[i] >= 0; i++)
-               set_bit(iforce->type->ff[i], input_dev->ffbit);
+       if (ff_effects) {
 
+               for (i = 0; iforce->type->ff[i] >= 0; i++)
+                       set_bit(iforce->type->ff[i], input_dev->ffbit);
+
+               error = input_ff_create(input_dev, ff_effects);
+               if (error) {
+                       input_free_device(input_dev);
+                       return error;
+               }
+
+               ff = input_dev->ff;
+               ff->upload = iforce_upload_effect;
+               ff->erase = iforce_erase_effect;
+               ff->set_gain = iforce_set_gain;
+               ff->set_autocenter = iforce_set_autocenter;
+               ff->playback = iforce_playback;
+       }
 /*
  * Register input device.
  */
index 76cb1f88f4e83d4177b8cb8c281861aef50325df..8632d47a7fbe588eed1a10cfa7f14b59845cef58 100644 (file)
@@ -140,7 +140,10 @@ static int mark_core_as_ready(struct iforce *iforce, unsigned short addr)
 {
        int i;
 
-       for (i = 0; i < iforce->dev->ff_effects_max; ++i) {
+       if (!iforce->dev->ff)
+               return 0;
+
+       for (i = 0; i < iforce->dev->ff->max_effects; ++i) {
                if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags) &&
                    (iforce->core_effects[i].mod1_chunk.start == addr ||
                     iforce->core_effects[i].mod2_chunk.start == addr)) {
@@ -229,19 +232,17 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data,
                        i = data[1] & 0x7f;
                        if (data[1] & 0x80) {
                                if (!test_and_set_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) {
-                               /* Report play event */
-                               input_report_ff_status(dev, i, FF_STATUS_PLAYING);
+                                       /* Report play event */
+                                       input_report_ff_status(dev, i, FF_STATUS_PLAYING);
                                }
-                       }
-                       else if (test_and_clear_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) {
+                       } else if (test_and_clear_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) {
                                /* Report stop event */
                                input_report_ff_status(dev, i, FF_STATUS_STOPPED);
                        }
                        if (LO(cmd) > 3) {
                                int j;
-                               for (j=3; j<LO(cmd); j+=2) {
+                               for (j = 3; j < LO(cmd); j += 2)
                                        mark_core_as_ready(iforce, data[j] | (data[j+1]<<8));
-                               }
                        }
                        break;
        }
index e9924d6f01b33991b975de0272588f6f0691ea7e..947df273984399384fd0e8aece218ac388cadb43 100644 (file)
 #define IFORCE_232     1
 #define IFORCE_USB     2
 
-#define FALSE 0
-#define TRUE 1
-
-#define FF_EFFECTS_MAX 32
+#define IFORCE_EFFECTS_MAX     32
 
 /* Each force feedback effect is made of one core effect, which can be
  * associated to at most to effect modifiers
 #define FF_CORE_UPDATE         5       /* Effect is being updated */
 #define FF_MODCORE_MAX         5
 
-#define CHECK_OWNERSHIP(i, iforce)     \
-       ((i) < FF_EFFECTS_MAX && i >= 0 && \
-       test_bit(FF_CORE_IS_USED, (iforce)->core_effects[(i)].flags) && \
-       (current->pid == 0 || \
-       (iforce)->core_effects[(i)].owner == current->pid))
-
 struct iforce_core_effect {
        /* Information about where modifiers are stored in the device's memory */
        struct resource mod1_chunk;
        struct resource mod2_chunk;
        unsigned long flags[NBITS(FF_MODCORE_MAX)];
-       pid_t owner;
-       /* Used to keep track of parameters of an effect. They are needed
-        * to know what parts of an effect changed in an update operation.
-        * We try to send only parameter packets if possible, as sending
-        * effect parameter requires the effect to be stoped and restarted
-        */
-       struct ff_effect effect;
 };
 
 #define FF_CMD_EFFECT          0x010e
@@ -145,7 +129,7 @@ struct iforce {
                                        /* Force Feedback */
        wait_queue_head_t wait;
        struct resource device_memory;
-       struct iforce_core_effect core_effects[FF_EFFECTS_MAX];
+       struct iforce_core_effect core_effects[IFORCE_EFFECTS_MAX];
        struct mutex mem_mutex;
 };
 
@@ -182,9 +166,9 @@ void iforce_dump_packet(char *msg, u16 cmd, unsigned char *data) ;
 int iforce_get_id_packet(struct iforce *iforce, char *packet);
 
 /* iforce-ff.c */
-int iforce_upload_periodic(struct iforce*, struct ff_effect*, int is_update);
-int iforce_upload_constant(struct iforce*, struct ff_effect*, int is_update);
-int iforce_upload_condition(struct iforce*, struct ff_effect*, int is_update);
+int iforce_upload_periodic(struct iforce *, struct ff_effect *, struct ff_effect *);
+int iforce_upload_constant(struct iforce *, struct ff_effect *, struct ff_effect *);
+int iforce_upload_condition(struct iforce *, struct ff_effect *, struct ff_effect *);
 
 /* Public variables */
 extern struct serio_driver iforce_serio_drv;
index 83eac3a66bc801d11f11d6f1535f3894b9950f18..679bde34d2478f058330711322ca03c7bf51b6ba 100644 (file)
@@ -121,6 +121,17 @@ config KEYBOARD_NEWTON
          To compile this driver as a module, choose M here: the
          module will be called newtonkbd.
 
+config KEYBOARD_STOWAWAY
+       tristate "Stowaway keyboard"
+       select SERIO
+       help
+         Say Y here if you have a Stowaway keyboard on a serial port.
+         Stowaway compatible keyboards like Dicota Input-PDA keyboard
+         are also supported by this driver.
+
+         To compile this driver as a module, choose M here: the
+         module will be called stowaway.
+
 config KEYBOARD_CORGI
        tristate "Corgi keyboard"
        depends on PXA_SHARPSL
@@ -166,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 b265391f1f10a226e6054d3496cb296f3deeafc7..4c79e7bc9d06df25bfd98a71a1acd480ab98201e 100644 (file)
@@ -11,6 +11,7 @@ obj-$(CONFIG_KEYBOARD_XTKBD)          += xtkbd.o
 obj-$(CONFIG_KEYBOARD_AMIGA)           += amikbd.o
 obj-$(CONFIG_KEYBOARD_LOCOMO)          += locomokbd.o
 obj-$(CONFIG_KEYBOARD_NEWTON)          += newtonkbd.o
+obj-$(CONFIG_KEYBOARD_STOWAWAY)                += stowaway.o
 obj-$(CONFIG_KEYBOARD_CORGI)           += corgikbd.o
 obj-$(CONFIG_KEYBOARD_SPITZ)           += spitzkbd.o
 obj-$(CONFIG_KEYBOARD_HIL)             += hil_kbd.o
index a86afd0a5ef13c95c869613c5fd4e67b7c414825..40244d4ce0f1696e6dc3179c7ab13e260884851a 100644 (file)
@@ -652,9 +652,7 @@ static int atkbd_probe(struct atkbd *atkbd)
                return 0;
        }
 
-       if (param[0] != 0xab && param[0] != 0xac &&     /* Regular and NCD Sun keyboards */
-           param[0] != 0x2b && param[0] != 0x5d &&     /* Trust keyboard, raw and translated */
-           param[0] != 0x60 && param[0] != 0x47)       /* NMB SGI keyboard, raw and translated */
+       if (!ps2_is_keyboard_id(param[0]))
                return -1;
 
        atkbd->id = (param[0] << 8) | param[1];
diff --git a/drivers/input/keyboard/stowaway.c b/drivers/input/keyboard/stowaway.c
new file mode 100644 (file)
index 0000000..04c54c5
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * Stowaway keyboard driver for Linux
+ */
+
+/*
+ *  Copyright (c) 2006 Marek Vasut
+ *
+ *  Based on Newton keyboard driver for Linux
+ *  by Justin Cormack
+ */
+
+/*
+ * 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
+ *
+ * Should you need to contact me, the author, you can do so either by
+ * e-mail - mail your message to <marek.vasut@gmail.com>, or by paper mail:
+ * Marek Vasut, Liskovecka 559, Frydek-Mistek, 738 01 Czech Republic
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/init.h>
+#include <linux/serio.h>
+
+#define DRIVER_DESC    "Stowaway keyboard driver"
+
+MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+#define SKBD_KEY_MASK  0x7f
+#define SKBD_RELEASE   0x80
+
+static unsigned char skbd_keycode[128] = {
+       KEY_1, KEY_2, KEY_3, KEY_Z, KEY_4, KEY_5, KEY_6, KEY_7,
+       0, KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y, KEY_GRAVE,
+       KEY_X, KEY_A, KEY_S, KEY_D, KEY_F, KEY_G, KEY_H, KEY_SPACE,
+       KEY_CAPSLOCK, KEY_TAB, KEY_LEFTCTRL, 0, 0, 0, 0, 0,
+       0, 0, 0, KEY_LEFTALT, 0, 0, 0, 0,
+       0, 0, 0, 0, KEY_C, KEY_V, KEY_B, KEY_N,
+       KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_HOME, KEY_8, KEY_9, KEY_0, KEY_ESC,
+       KEY_LEFTBRACE, KEY_RIGHTBRACE, KEY_BACKSLASH, KEY_END, KEY_U, KEY_I, KEY_O, KEY_P,
+       KEY_APOSTROPHE, KEY_ENTER, KEY_PAGEUP,0, KEY_J, KEY_K, KEY_L, KEY_SEMICOLON,
+       KEY_SLASH, KEY_UP, KEY_PAGEDOWN, 0,KEY_M, KEY_COMMA, KEY_DOT, KEY_INSERT,
+       KEY_DELETE, KEY_LEFT, KEY_DOWN, KEY_RIGHT,  0, 0, 0,
+       KEY_LEFTSHIFT, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0,
+       0, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7,
+       KEY_F8, KEY_F9, KEY_F10, KEY_F11, KEY_F12, 0, 0, 0
+};
+
+struct skbd {
+       unsigned char keycode[128];
+       struct input_dev *dev;
+       struct serio *serio;
+       char phys[32];
+};
+
+static irqreturn_t skbd_interrupt(struct serio *serio, unsigned char data,
+                                 unsigned int flags, struct pt_regs *regs)
+{
+       struct skbd *skbd = serio_get_drvdata(serio);
+       struct input_dev *dev = skbd->dev;
+
+       if (skbd->keycode[data & SKBD_KEY_MASK]) {
+               input_regs(dev, regs);
+               input_report_key(dev, skbd->keycode[data & SKBD_KEY_MASK],
+                                !(data & SKBD_RELEASE));
+               input_sync(dev);
+       }
+
+       return IRQ_HANDLED;
+}
+
+static int skbd_connect(struct serio *serio, struct serio_driver *drv)
+{
+       struct skbd *skbd;
+       struct input_dev *input_dev;
+       int err = -ENOMEM;
+       int i;
+
+       skbd = kzalloc(sizeof(struct skbd), GFP_KERNEL);
+       input_dev = input_allocate_device();
+       if (!skbd || !input_dev)
+               goto fail1;
+
+       skbd->serio = serio;
+       skbd->dev = input_dev;
+       snprintf(skbd->phys, sizeof(skbd->phys), "%s/input0", serio->phys);
+       memcpy(skbd->keycode, skbd_keycode, sizeof(skbd->keycode));
+
+       input_dev->name = "Stowaway Keyboard";
+       input_dev->phys = skbd->phys;
+       input_dev->id.bustype = BUS_RS232;
+       input_dev->id.vendor = SERIO_STOWAWAY;
+       input_dev->id.product = 0x0001;
+       input_dev->id.version = 0x0100;
+       input_dev->cdev.dev = &serio->dev;
+       input_dev->private = skbd;
+
+       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+       input_dev->keycode = skbd->keycode;
+       input_dev->keycodesize = sizeof(unsigned char);
+       input_dev->keycodemax = ARRAY_SIZE(skbd_keycode);
+       for (i = 0; i < ARRAY_SIZE(skbd_keycode); i++)
+               set_bit(skbd_keycode[i], input_dev->keybit);
+       clear_bit(0, input_dev->keybit);
+
+       serio_set_drvdata(serio, skbd);
+
+       err = serio_open(serio, drv);
+       if (err)
+               goto fail2;
+
+       err = input_register_device(skbd->dev);
+       if (err)
+               goto fail3;
+
+       return 0;
+
+ fail3: serio_close(serio);
+ fail2:        serio_set_drvdata(serio, NULL);
+ fail1:        input_free_device(input_dev);
+       kfree(skbd);
+       return err;
+}
+
+static void skbd_disconnect(struct serio *serio)
+{
+       struct skbd *skbd = serio_get_drvdata(serio);
+
+       serio_close(serio);
+       serio_set_drvdata(serio, NULL);
+       input_unregister_device(skbd->dev);
+       kfree(skbd);
+}
+
+static struct serio_device_id skbd_serio_ids[] = {
+       {
+               .type   = SERIO_RS232,
+               .proto  = SERIO_STOWAWAY,
+               .id     = SERIO_ANY,
+               .extra  = SERIO_ANY,
+       },
+       { 0 }
+};
+
+MODULE_DEVICE_TABLE(serio, skbd_serio_ids);
+
+static struct serio_driver skbd_drv = {
+       .driver         = {
+               .name   = "stowaway",
+       },
+       .description    = DRIVER_DESC,
+       .id_table       = skbd_serio_ids,
+       .interrupt      = skbd_interrupt,
+       .connect        = skbd_connect,
+       .disconnect     = skbd_disconnect,
+};
+
+static int __init skbd_init(void)
+{
+       serio_register_driver(&skbd_drv);
+       return 0;
+}
+
+static void __exit skbd_exit(void)
+{
+       serio_unregister_driver(&skbd_drv);
+}
+
+module_init(skbd_init);
+module_exit(skbd_exit);
index d723e9ad7c41a103ce092db1b45068b98b8acd9b..9516439b7c78837ed83ede2d6559c194b4aeb50e 100644 (file)
@@ -20,6 +20,9 @@
  * Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
  *
  * Changes/Revisions:
+ *     0.3     09/04/2006 (Anssi Hannula <anssi.hannula@gmail.com>)
+ *             - updated ff support for the changes in kernel interface
+ *             - added MODULE_VERSION
  *     0.2     16/10/2004 (Micah Dowty <micah@navi.cx>)
  *             - added force feedback support
  *              - added UI_SET_PHYS
@@ -107,18 +110,31 @@ static int uinput_request_submit(struct input_dev *dev, struct uinput_request *r
        return request->retval;
 }
 
-static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect)
+static void uinput_dev_set_gain(struct input_dev *dev, u16 gain)
+{
+       uinput_dev_event(dev, EV_FF, FF_GAIN, gain);
+}
+
+static void uinput_dev_set_autocenter(struct input_dev *dev, u16 magnitude)
+{
+       uinput_dev_event(dev, EV_FF, FF_AUTOCENTER, magnitude);
+}
+
+static int uinput_dev_playback(struct input_dev *dev, int effect_id, int value)
+{
+       return uinput_dev_event(dev, EV_FF, effect_id, value);
+}
+
+static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect, struct ff_effect *old)
 {
        struct uinput_request request;
        int retval;
 
-       if (!test_bit(EV_FF, dev->evbit))
-               return -ENOSYS;
-
        request.id = -1;
        init_completion(&request.done);
        request.code = UI_FF_UPLOAD;
-       request.u.effect = effect;
+       request.u.upload.effect = effect;
+       request.u.upload.old = old;
 
        retval = uinput_request_reserve_slot(dev->private, &request);
        if (!retval)
@@ -168,6 +184,7 @@ static void uinput_destroy_device(struct uinput_device *udev)
 
 static int uinput_create_device(struct uinput_device *udev)
 {
+       struct input_dev *dev = udev->dev;
        int error;
 
        if (udev->state != UIST_SETUP_COMPLETE) {
@@ -175,15 +192,29 @@ static int uinput_create_device(struct uinput_device *udev)
                return -EINVAL;
        }
 
-       error = input_register_device(udev->dev);
-       if (error) {
-               uinput_destroy_device(udev);
-               return error;
+       if (udev->ff_effects_max) {
+               error = input_ff_create(dev, udev->ff_effects_max);
+               if (error)
+                       goto fail1;
+
+               dev->ff->upload = uinput_dev_upload_effect;
+               dev->ff->erase = uinput_dev_erase_effect;
+               dev->ff->playback = uinput_dev_playback;
+               dev->ff->set_gain = uinput_dev_set_gain;
+               dev->ff->set_autocenter = uinput_dev_set_autocenter;
        }
 
+       error = input_register_device(udev->dev);
+       if (error)
+               goto fail2;
+
        udev->state = UIST_CREATED;
 
        return 0;
+
+ fail2:        input_ff_destroy(dev);
+ fail1: uinput_destroy_device(udev);
+       return error;
 }
 
 static int uinput_open(struct inode *inode, struct file *file)
@@ -243,8 +274,6 @@ static int uinput_allocate_device(struct uinput_device *udev)
                return -ENOMEM;
 
        udev->dev->event = uinput_dev_event;
-       udev->dev->upload_effect = uinput_dev_upload_effect;
-       udev->dev->erase_effect = uinput_dev_erase_effect;
        udev->dev->private = udev;
 
        return 0;
@@ -278,6 +307,8 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu
                goto exit;
        }
 
+       udev->ff_effects_max = user_dev->ff_effects_max;
+
        size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1;
        if (!size) {
                retval = -EINVAL;
@@ -296,7 +327,6 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu
        dev->id.vendor  = user_dev->id.vendor;
        dev->id.product = user_dev->id.product;
        dev->id.version = user_dev->id.version;
-       dev->ff_effects_max = user_dev->ff_effects_max;
 
        size = sizeof(int) * (ABS_MAX + 1);
        memcpy(dev->absmax, user_dev->absmax, size);
@@ -525,12 +555,17 @@ static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                                break;
                        }
                        req = uinput_request_find(udev, ff_up.request_id);
-                       if (!(req && req->code == UI_FF_UPLOAD && req->u.effect)) {
+                       if (!(req && req->code == UI_FF_UPLOAD && req->u.upload.effect)) {
                                retval = -EINVAL;
                                break;
                        }
                        ff_up.retval = 0;
-                       memcpy(&ff_up.effect, req->u.effect, sizeof(struct ff_effect));
+                       memcpy(&ff_up.effect, req->u.upload.effect, sizeof(struct ff_effect));
+                       if (req->u.upload.old)
+                               memcpy(&ff_up.old, req->u.upload.old, sizeof(struct ff_effect));
+                       else
+                               memset(&ff_up.old, 0, sizeof(struct ff_effect));
+
                        if (copy_to_user(p, &ff_up, sizeof(ff_up))) {
                                retval = -EFAULT;
                                break;
@@ -561,12 +596,11 @@ static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                                break;
                        }
                        req = uinput_request_find(udev, ff_up.request_id);
-                       if (!(req && req->code == UI_FF_UPLOAD && req->u.effect)) {
+                       if (!(req && req->code == UI_FF_UPLOAD && req->u.upload.effect)) {
                                retval = -EINVAL;
                                break;
                        }
                        req->retval = ff_up.retval;
-                       memcpy(req->u.effect, &ff_up.effect, sizeof(struct ff_effect));
                        uinput_request_done(udev, req);
                        break;
 
@@ -622,6 +656,7 @@ static void __exit uinput_exit(void)
 MODULE_AUTHOR("Aristeu Sergio Rozanski Filho");
 MODULE_DESCRIPTION("User level driver support for input subsystem");
 MODULE_LICENSE("GPL");
+MODULE_VERSION("0.3");
 
 module_init(uinput_init);
 module_exit(uinput_exit);
index de0f46dd96922020abda38f24bf0975f59bb7e46..4639537336fc116c9eeb62dcbb5741027e342e7b 100644 (file)
@@ -248,13 +248,10 @@ static int __init dmi_matched(struct dmi_system_id *dmi)
 
        keymap = dmi->driver_data;
        for (key = keymap; key->type != KE_END; key++) {
-               if (key->type == KE_WIFI) {
+               if (key->type == KE_WIFI)
                        have_wifi = 1;
-                       break;
-               } else if (key->type == KE_BLUETOOTH) {
+               else if (key->type == KE_BLUETOOTH)
                        have_bluetooth = 1;
-                       break;
-               }
        }
        return 1;
 }
@@ -389,7 +386,16 @@ static struct dmi_system_id dmi_ids[] __initdata = {
                },
                .driver_data = keymap_acer_travelmate_240
        },
-        {
+       {
+               .callback = dmi_matched,
+               .ident = "Acer TravelMate 2424NWXCi",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2420"),
+               },
+               .driver_data = keymap_acer_travelmate_240
+       },
+       {
                .callback = dmi_matched,
                .ident = "AOpen 1559AS",
                .matches = {
index 070d75330afd335de4dcf1691477aeb1bc8593e9..450b68a619fd4ab375db67d0b85567a1ef5455de 100644 (file)
@@ -36,7 +36,7 @@
 #define ALPS_PASS      0x20
 #define ALPS_FW_BK_2   0x40
 
-static struct alps_model_info alps_model_data[] = {
+static const struct alps_model_info alps_model_data[] = {
        { { 0x33, 0x02, 0x0a }, 0x88, 0xf8, ALPS_OLDPROTO },            /* UMAX-530T */
        { { 0x53, 0x02, 0x0a }, 0xf8, 0xf8, 0 },
        { { 0x53, 0x02, 0x14 }, 0xf8, 0xf8, 0 },
@@ -209,10 +209,10 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse, struct pt_regs *
        return PSMOUSE_GOOD_DATA;
 }
 
-static struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *version)
+static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *version)
 {
        struct ps2dev *ps2dev = &psmouse->ps2dev;
-       unsigned char rates[] = { 0, 10, 20, 40, 60, 80, 100, 200 };
+       static const unsigned char rates[] = { 0, 10, 20, 40, 60, 80, 100, 200 };
        unsigned char param[4];
        int i;
 
@@ -504,7 +504,7 @@ init_fail:
 int alps_detect(struct psmouse *psmouse, int set_properties)
 {
        int version;
-       struct alps_model_info *model;
+       const struct alps_model_info *model;
 
        if (!(model = alps_get_model(psmouse, &version)))
                return -1;
index e428f8d5d12ece57db9e20818d11088de71e1a12..69db7325a4944a79dc2aef6a925cdb329a262a24 100644 (file)
@@ -25,7 +25,7 @@ struct alps_data {
        struct input_dev *dev2;         /* Relative device */
        char name[32];                  /* Name */
        char phys[32];                  /* Phys */
-       struct alps_model_info *i;      /* Info */
+       const struct alps_model_info *i;/* Info */
        int prev_fin;                   /* Finger bit from previous packet */
 };
 
index c14395ba798005d31a14b7c3c0e135548ed4c03d..5e9d25067513850920d4589c029f4056f4fd3625 100644 (file)
@@ -115,13 +115,15 @@ static int lifebook_absolute_mode(struct psmouse *psmouse)
 
 static void lifebook_set_resolution(struct psmouse *psmouse, unsigned int resolution)
 {
-       unsigned char params[] = { 0, 1, 2, 2, 3 };
+       static const unsigned char params[] = { 0, 1, 2, 2, 3 };
+       unsigned char p;
 
        if (resolution == 0 || resolution > 400)
                resolution = 400;
 
-       ps2_command(&psmouse->ps2dev, &params[resolution / 100], PSMOUSE_CMD_SETRES);
-       psmouse->resolution = 50 << params[resolution / 100];
+       p = params[resolution / 100];
+       ps2_command(&psmouse->ps2dev, &p, PSMOUSE_CMD_SETRES);
+       psmouse->resolution = 50 << p;
 }
 
 static void lifebook_disconnect(struct psmouse *psmouse)
index 54b696cfe1e33be4bf94b599ab8f5cc71e4562c7..7972eecbcfe4184863bdb84e0a3dda6eff31f854 100644 (file)
@@ -30,9 +30,9 @@
 #define PS2PP_NAV_BTN          0x20
 
 struct ps2pp_info {
-       const int model;
-       unsigned const int kind;
-       unsigned const int features;
+       u8 model;
+       u8 kind;
+       u16 features;
 };
 
 /*
@@ -199,9 +199,9 @@ static void ps2pp_disconnect(struct psmouse *psmouse)
        device_remove_file(&psmouse->ps2dev.serio->dev, &psmouse_attr_smartscroll.dattr);
 }
 
-static struct ps2pp_info *get_model_info(unsigned char model)
+static const struct ps2pp_info *get_model_info(unsigned char model)
 {
-       static struct ps2pp_info ps2pp_list[] = {
+       static const struct ps2pp_info ps2pp_list[] = {
                { 12,   0,                      PS2PP_SIDE_BTN},
                { 13,   0,                      0 },
                { 15,   PS2PP_KIND_MX,                                  /* MX1000 */
@@ -215,6 +215,7 @@ static struct ps2pp_info *get_model_info(unsigned char model)
                { 51,   0,                      0 },
                { 52,   PS2PP_KIND_WHEEL,       PS2PP_SIDE_BTN | PS2PP_WHEEL },
                { 53,   PS2PP_KIND_WHEEL,       PS2PP_WHEEL },
+               { 56,   PS2PP_KIND_WHEEL,       PS2PP_SIDE_BTN | PS2PP_WHEEL }, /* Cordless MouseMan Wheel */
                { 61,   PS2PP_KIND_MX,                                  /* MX700 */
                                PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN |
                                PS2PP_EXTRA_BTN | PS2PP_NAV_BTN },
@@ -244,12 +245,11 @@ static struct ps2pp_info *get_model_info(unsigned char model)
                                PS2PP_EXTRA_BTN | PS2PP_NAV_BTN },
                { 114,  PS2PP_KIND_MX,                                  /* MX310 */
                                PS2PP_WHEEL | PS2PP_SIDE_BTN |
-                               PS2PP_TASK_BTN | PS2PP_EXTRA_BTN },
-               { }
+                               PS2PP_TASK_BTN | PS2PP_EXTRA_BTN }
        };
        int i;
 
-       for (i = 0; ps2pp_list[i].model; i++)
+       for (i = 0; i < ARRAY_SIZE(ps2pp_list); i++)
                if (model == ps2pp_list[i].model)
                        return &ps2pp_list[i];
 
@@ -261,7 +261,8 @@ static struct ps2pp_info *get_model_info(unsigned char model)
  * Set up input device's properties based on the detected mouse model.
  */
 
-static void ps2pp_set_model_properties(struct psmouse *psmouse, struct ps2pp_info *model_info,
+static void ps2pp_set_model_properties(struct psmouse *psmouse,
+                                      const struct ps2pp_info *model_info,
                                       int using_ps2pp)
 {
        struct input_dev *input_dev = psmouse->dev;
@@ -327,7 +328,7 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties)
        struct ps2dev *ps2dev = &psmouse->ps2dev;
        unsigned char param[4];
        unsigned char model, buttons;
-       struct ps2pp_info *model_info;
+       const struct ps2pp_info *model_info;
        int use_ps2pp = 0;
 
        param[0] = 0;
@@ -349,7 +350,7 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties)
 /*
  * Do Logitech PS2++ / PS2T++ magic init.
  */
-               if (model == 97) { /* Touch Pad 3 */
+               if (model_info->kind == PS2PP_KIND_TP3) { /* Touch Pad 3 */
 
                        /* Unprotect RAM */
                        param[0] = 0x11; param[1] = 0x04; param[2] = 0x68;
index 343afa38f4c2d2b1c38ae809097ea343d44a670a..9fb7eb6b0f71f3bb9f5d7972e99627146a463fa7 100644 (file)
@@ -112,8 +112,8 @@ static struct workqueue_struct *kpsmoused_wq;
 
 struct psmouse_protocol {
        enum psmouse_type type;
-       char *name;
-       char *alias;
+       const char *name;
+       const char *alias;
        int maxproto;
        int (*detect)(struct psmouse *, int);
        int (*init)(struct psmouse *);
@@ -507,15 +507,17 @@ static int thinking_detect(struct psmouse *psmouse, int set_properties)
 {
        struct ps2dev *ps2dev = &psmouse->ps2dev;
        unsigned char param[2];
-       unsigned char seq[] = { 20, 60, 40, 20, 20, 60, 40, 20, 20, 0 };
+       static const unsigned char seq[] = { 20, 60, 40, 20, 20, 60, 40, 20, 20 };
        int i;
 
        param[0] = 10;
        ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
        param[0] = 0;
        ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
-       for (i = 0; seq[i]; i++)
-               ps2_command(ps2dev, seq + i, PSMOUSE_CMD_SETRATE);
+       for (i = 0; i < ARRAY_SIZE(seq); i++) {
+               param[0] = seq[i];
+               ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
+       }
        ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);
 
        if (param[0] != 2)
@@ -652,7 +654,7 @@ static int psmouse_extensions(struct psmouse *psmouse,
        return PSMOUSE_PS2;
 }
 
-static struct psmouse_protocol psmouse_protocols[] = {
+static const struct psmouse_protocol psmouse_protocols[] = {
        {
                .type           = PSMOUSE_PS2,
                .name           = "PS/2",
@@ -726,7 +728,7 @@ static struct psmouse_protocol psmouse_protocols[] = {
        },
 };
 
-static struct psmouse_protocol *psmouse_protocol_by_type(enum psmouse_type type)
+static const struct psmouse_protocol *psmouse_protocol_by_type(enum psmouse_type type)
 {
        int i;
 
@@ -738,9 +740,9 @@ static struct psmouse_protocol *psmouse_protocol_by_type(enum psmouse_type type)
        return &psmouse_protocols[0];
 }
 
-static struct psmouse_protocol *psmouse_protocol_by_name(const char *name, size_t len)
+static const struct psmouse_protocol *psmouse_protocol_by_name(const char *name, size_t len)
 {
-       struct psmouse_protocol *p;
+       const struct psmouse_protocol *p;
        int i;
 
        for (i = 0; i < ARRAY_SIZE(psmouse_protocols); i++) {
@@ -795,13 +797,15 @@ static int psmouse_probe(struct psmouse *psmouse)
 
 void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution)
 {
-       unsigned char params[] = { 0, 1, 2, 2, 3 };
+       static const unsigned char params[] = { 0, 1, 2, 2, 3 };
+       unsigned char p;
 
        if (resolution == 0 || resolution > 200)
                resolution = 200;
 
-       ps2_command(&psmouse->ps2dev, &params[resolution / 50], PSMOUSE_CMD_SETRES);
-       psmouse->resolution = 25 << params[resolution / 50];
+       p = params[resolution / 50];
+       ps2_command(&psmouse->ps2dev, &p, PSMOUSE_CMD_SETRES);
+       psmouse->resolution = 25 << p;
 }
 
 /*
@@ -810,12 +814,14 @@ void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution)
 
 static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate)
 {
-       unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 };
+       static const unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 };
+       unsigned char r;
        int i = 0;
 
        while (rates[i] > rate) i++;
-       ps2_command(&psmouse->ps2dev, &rates[i], PSMOUSE_CMD_SETRATE);
-       psmouse->rate = rates[i];
+       r = rates[i];
+       ps2_command(&psmouse->ps2dev, &r, PSMOUSE_CMD_SETRATE);
+       psmouse->rate = r;
 }
 
 /*
@@ -1031,7 +1037,7 @@ static void psmouse_disconnect(struct serio *serio)
        mutex_unlock(&psmouse_mutex);
 }
 
-static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_protocol *proto)
+static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse_protocol *proto)
 {
        struct input_dev *input_dev = psmouse->dev;
 
@@ -1362,7 +1368,7 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
        struct serio *serio = psmouse->ps2dev.serio;
        struct psmouse *parent = NULL;
        struct input_dev *new_dev;
-       struct psmouse_protocol *proto;
+       const struct psmouse_protocol *proto;
        int retry = 0;
 
        if (!(proto = psmouse_protocol_by_name(buf, count)))
@@ -1459,7 +1465,7 @@ static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, void *data,
 
 static int psmouse_set_maxproto(const char *val, struct kernel_param *kp)
 {
-       struct psmouse_protocol *proto;
+       const struct psmouse_protocol *proto;
 
        if (!val)
                return -EINVAL;
index 0023501a5b634fd086837d3e1e9dc49f116414d4..680b323538847cbc53dfa7a99f9d5ae9b97d97ce 100644 (file)
@@ -42,7 +42,7 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
-static char *sermouse_protocols[] = { "None", "Mouse Systems Mouse", "Sun Mouse", "Microsoft Mouse",
+static const char *sermouse_protocols[] = { "None", "Mouse Systems Mouse", "Sun Mouse", "Microsoft Mouse",
                                        "Logitech M+ Mouse", "Microsoft MZ Mouse", "Logitech MZ+ Mouse",
                                        "Logitech MZ++ Mouse"};
 
index ad5d0a85e960157b335915e693a87872e4a9bf96..392108c436baca504abd345b4013ae90799e41e5 100644 (file)
@@ -430,11 +430,11 @@ static void synaptics_process_packet(struct psmouse *psmouse)
 
 static int synaptics_validate_byte(unsigned char packet[], int idx, unsigned char pkt_type)
 {
-       static unsigned char newabs_mask[]      = { 0xC8, 0x00, 0x00, 0xC8, 0x00 };
-       static unsigned char newabs_rel_mask[]  = { 0xC0, 0x00, 0x00, 0xC0, 0x00 };
-       static unsigned char newabs_rslt[]      = { 0x80, 0x00, 0x00, 0xC0, 0x00 };
-       static unsigned char oldabs_mask[]      = { 0xC0, 0x60, 0x00, 0xC0, 0x60 };
-       static unsigned char oldabs_rslt[]      = { 0xC0, 0x00, 0x00, 0x80, 0x00 };
+       static const unsigned char newabs_mask[]        = { 0xC8, 0x00, 0x00, 0xC8, 0x00 };
+       static const unsigned char newabs_rel_mask[]    = { 0xC0, 0x00, 0x00, 0xC0, 0x00 };
+       static const unsigned char newabs_rslt[]        = { 0x80, 0x00, 0x00, 0xC0, 0x00 };
+       static const unsigned char oldabs_mask[]        = { 0xC0, 0x60, 0x00, 0xC0, 0x60 };
+       static const unsigned char oldabs_rslt[]        = { 0xC0, 0x00, 0x00, 0x80, 0x00 };
 
        if (idx < 0 || idx > 4)
                return 0;
index 1f851acab30db2f692ab74886256701409432110..a22a74a2a3dcc6e781b79609360830b95208c026 100644 (file)
@@ -614,7 +614,7 @@ static unsigned int mousedev_poll(struct file *file, poll_table *wait)
                (list->mousedev->exist ? 0 : (POLLHUP | POLLERR));
 }
 
-static struct file_operations mousedev_fops = {
+static const struct file_operations mousedev_fops = {
        .owner =        THIS_MODULE,
        .read =         mousedev_read,
        .write =        mousedev_write,
@@ -624,7 +624,8 @@ static struct file_operations mousedev_fops = {
        .fasync =       mousedev_fasync,
 };
 
-static struct input_handle *mousedev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
+static struct input_handle *mousedev_connect(struct input_handler *handler, struct input_dev *dev,
+                                            const struct input_device_id *id)
 {
        struct mousedev *mousedev;
        struct class_device *cdev;
@@ -688,7 +689,7 @@ static void mousedev_disconnect(struct input_handle *handle)
        }
 }
 
-static struct input_device_id mousedev_ids[] = {
+static const struct input_device_id mousedev_ids[] = {
        {
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_RELBIT,
                .evbit = { BIT(EV_KEY) | BIT(EV_REL) },
@@ -737,7 +738,12 @@ static int psaux_registered;
 
 static int __init mousedev_init(void)
 {
-       input_register_handler(&mousedev_handler);
+       struct class_device *cdev;
+       int error;
+
+       error = input_register_handler(&mousedev_handler);
+       if (error)
+               return error;
 
        memset(&mousedev_mix, 0, sizeof(struct mousedev));
        INIT_LIST_HEAD(&mousedev_mix.list);
@@ -746,12 +752,20 @@ static int __init mousedev_init(void)
        mousedev_mix.exist = 1;
        mousedev_mix.minor = MOUSEDEV_MIX;
 
-       class_device_create(&input_class, NULL,
+       cdev = class_device_create(&input_class, NULL,
                        MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX), NULL, "mice");
+       if (IS_ERR(cdev)) {
+               input_unregister_handler(&mousedev_handler);
+               return PTR_ERR(cdev);
+       }
 
 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
-       if (!(psaux_registered = !misc_register(&psaux_mouse)))
-               printk(KERN_WARNING "mice: could not misc_register the device\n");
+       error = misc_register(&psaux_mouse);
+       if (error)
+               printk(KERN_WARNING "mice: could not register psaux device, "
+                       "error: %d\n", error);
+       else
+               psaux_registered = 1;
 #endif
 
        printk(KERN_INFO "mice: PS/2 mouse device common for all mice\n");
index 51a519e24b6d07bd146206d47cd1293719dedb48..ee82464a2fa73c5bfd2b203fdfe68a8cd6ccfb61 100644 (file)
@@ -98,7 +98,7 @@ static void power_event(struct input_handle *handle, unsigned int type,
 
 static struct input_handle *power_connect(struct input_handler *handler,
                                          struct input_dev *dev,
-                                         struct input_device_id *id)
+                                         const struct input_device_id *id)
 {
        struct input_handle *handle;
 
@@ -120,7 +120,7 @@ static void power_disconnect(struct input_handle *handle)
        kfree(handle);
 }
 
-static struct input_device_id power_ids[] = {
+static const struct input_device_id power_ids[] = {
        {
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
                .evbit = { BIT(EV_KEY) },
@@ -150,8 +150,7 @@ static struct input_handler power_handler = {
 
 static int __init power_init(void)
 {
-       input_register_handler(&power_handler);
-       return 0;
+       return input_register_handler(&power_handler);
 }
 
 static void __exit power_exit(void)
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 f606e96bc2f4b5e4f5e04f22f0440c94c3453607..8738edda661001236e0db92c0607ec98fa0496b7 100644 (file)
@@ -159,6 +159,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"),
                },
        },
+       {
+               .ident = "Toshiba Equium A110",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"),
+               },
+       },
        {
                .ident = "Alienware Sentia",
                .matches = {
@@ -180,6 +187,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"),
                },
        },
+       {
+               .ident = "Amoi M636/A737",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"),
+               },
+       },
        { }
 };
 
index 06a3f25657dd29062455027e076cbab0c99165b5..1bb0c76a9259b182c2153a86472965712b134c6d 100644 (file)
@@ -90,46 +90,24 @@ static DEFINE_SPINLOCK(i8042_lock);
 struct i8042_port {
        struct serio *serio;
        int irq;
-       unsigned char disable;
-       unsigned char irqen;
        unsigned char exists;
        signed char mux;
-       char name[8];
 };
 
 #define I8042_KBD_PORT_NO      0
 #define I8042_AUX_PORT_NO      1
 #define I8042_MUX_PORT_NO      2
 #define I8042_NUM_PORTS                (I8042_NUM_MUX_PORTS + 2)
-static struct i8042_port i8042_ports[I8042_NUM_PORTS] = {
-       {
-               .disable        = I8042_CTR_KBDDIS,
-               .irqen          = I8042_CTR_KBDINT,
-               .mux            = -1,
-               .name           = "KBD",
-       },
-       {
-               .disable        = I8042_CTR_AUXDIS,
-               .irqen          = I8042_CTR_AUXINT,
-               .mux            = -1,
-               .name           = "AUX",
-       }
-};
+
+static struct i8042_port i8042_ports[I8042_NUM_PORTS];
 
 static unsigned char i8042_initial_ctr;
 static unsigned char i8042_ctr;
-static unsigned char i8042_mux_open;
 static unsigned char i8042_mux_present;
-static struct timer_list i8042_timer;
+static unsigned char i8042_kbd_irq_registered;
+static unsigned char i8042_aux_irq_registered;
 static struct platform_device *i8042_platform_device;
 
-
-/*
- * Shared IRQ's require a device pointer, but this driver doesn't support
- * multiple devices
- */
-#define i8042_request_irq_cookie (&i8042_timer)
-
 static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 
 /*
@@ -141,6 +119,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static int i8042_wait_read(void)
 {
        int i = 0;
+
        while ((~i8042_read_status() & I8042_STR_OBF) && (i < I8042_CTL_TIMEOUT)) {
                udelay(50);
                i++;
@@ -151,6 +130,7 @@ static int i8042_wait_read(void)
 static int i8042_wait_write(void)
 {
        int i = 0;
+
        while ((i8042_read_status() & I8042_STR_IBF) && (i < I8042_CTL_TIMEOUT)) {
                udelay(50);
                i++;
@@ -192,48 +172,57 @@ static int i8042_flush(void)
  * encoded in bits 8-11 of the command number.
  */
 
-static int i8042_command(unsigned char *param, int command)
+static int __i8042_command(unsigned char *param, int command)
 {
-       unsigned long flags;
-       int i, retval, auxerr = 0;
+       int i, error;
 
        if (i8042_noloop && command == I8042_CMD_AUX_LOOP)
                return -1;
 
-       spin_lock_irqsave(&i8042_lock, flags);
-
-       if ((retval = i8042_wait_write()))
-               goto out;
+       error = i8042_wait_write();
+       if (error)
+               return error;
 
        dbg("%02x -> i8042 (command)", command & 0xff);
        i8042_write_command(command & 0xff);
 
        for (i = 0; i < ((command >> 12) & 0xf); i++) {
-               if ((retval = i8042_wait_write()))
-                       goto out;
+               error = i8042_wait_write();
+               if (error)
+                       return error;
                dbg("%02x -> i8042 (parameter)", param[i]);
                i8042_write_data(param[i]);
        }
 
        for (i = 0; i < ((command >> 8) & 0xf); i++) {
-               if ((retval = i8042_wait_read()))
-                       goto out;
+               error = i8042_wait_read();
+               if (error) {
+                       dbg("     -- i8042 (timeout)");
+                       return error;
+               }
 
                if (command == I8042_CMD_AUX_LOOP &&
                    !(i8042_read_status() & I8042_STR_AUXDATA)) {
-                       retval = auxerr = -1;
-                       goto out;
+                       dbg("     -- i8042 (auxerr)");
+                       return -1;
                }
 
                param[i] = i8042_read_data();
                dbg("%02x <- i8042 (return)", param[i]);
        }
 
-       if (retval)
-               dbg("     -- i8042 (%s)", auxerr ? "auxerr" : "timeout");
+       return 0;
+}
 
- out:
+static int i8042_command(unsigned char *param, int command)
+{
+       unsigned long flags;
+       int retval;
+
+       spin_lock_irqsave(&i8042_lock, flags);
+       retval = __i8042_command(param, command);
        spin_unlock_irqrestore(&i8042_lock, flags);
+
        return retval;
 }
 
@@ -248,7 +237,7 @@ static int i8042_kbd_write(struct serio *port, unsigned char c)
 
        spin_lock_irqsave(&i8042_lock, flags);
 
-       if(!(retval = i8042_wait_write())) {
+       if (!(retval = i8042_wait_write())) {
                dbg("%02x -> i8042 (kbd-data)", c);
                i8042_write_data(c);
        }
@@ -286,100 +275,6 @@ static int i8042_aux_write(struct serio *serio, unsigned char c)
        return retval;
 }
 
-/*
- * i8042_activate_port() enables port on a chip.
- */
-
-static int i8042_activate_port(struct i8042_port *port)
-{
-       if (!port->serio)
-               return -1;
-
-       i8042_flush();
-
-       /*
-        * Enable port again here because it is disabled if we are
-        * resuming (normally it is enabled already).
-        */
-       i8042_ctr &= ~port->disable;
-
-       i8042_ctr |= port->irqen;
-
-       if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
-               i8042_ctr &= ~port->irqen;
-               return -1;
-       }
-
-       return 0;
-}
-
-
-/*
- * i8042_open() is called when a port is open by the higher layer.
- * It allocates the interrupt and calls i8042_enable_port.
- */
-
-static int i8042_open(struct serio *serio)
-{
-       struct i8042_port *port = serio->port_data;
-
-       if (port->mux != -1)
-               if (i8042_mux_open++)
-                       return 0;
-
-       if (request_irq(port->irq, i8042_interrupt,
-                       IRQF_SHARED, "i8042", i8042_request_irq_cookie)) {
-               printk(KERN_ERR "i8042.c: Can't get irq %d for %s, unregistering the port.\n", port->irq, port->name);
-               goto irq_fail;
-       }
-
-       if (i8042_activate_port(port)) {
-               printk(KERN_ERR "i8042.c: Can't activate %s, unregistering the port\n", port->name);
-               goto activate_fail;
-       }
-
-       i8042_interrupt(0, NULL, NULL);
-
-       return 0;
-
- activate_fail:
-       free_irq(port->irq, i8042_request_irq_cookie);
-
- irq_fail:
-       serio_unregister_port_delayed(serio);
-
-       return -1;
-}
-
-/*
- * i8042_close() frees the interrupt, so that it can possibly be used
- * by another driver. We never know - if the user doesn't have a mouse,
- * the BIOS could have used the AUX interrupt for PCI.
- */
-
-static void i8042_close(struct serio *serio)
-{
-       struct i8042_port *port = serio->port_data;
-
-       if (port->mux != -1)
-               if (--i8042_mux_open)
-                       return;
-
-       i8042_ctr &= ~port->irqen;
-
-       if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
-               printk(KERN_WARNING "i8042.c: Can't write CTR while closing %s.\n", port->name);
-/*
- * We still want to continue and free IRQ so if more data keeps coming in
- * kernel will just ignore the irq.
- */
-       }
-
-       free_irq(port->irq, i8042_request_irq_cookie);
-
-       i8042_flush();
-}
-
 /*
  * i8042_start() is called by serio core when port is about to finish
  * registering. It will mark port as existing so i8042_interrupt can
@@ -423,8 +318,6 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        unsigned int port_no;
        int ret;
 
-       mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
-
        spin_lock_irqsave(&i8042_lock, flags);
        str = i8042_read_status();
        if (unlikely(~str & I8042_STR_OBF)) {
@@ -480,8 +373,8 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
        port = &i8042_ports[port_no];
 
-       dbg("%02x <- i8042 (interrupt, %s, %d%s%s)",
-           data, port->name, irq,
+       dbg("%02x <- i8042 (interrupt, %d, %d%s%s)",
+           data, port_no, irq,
            dfl & SERIO_PARITY ? ", bad parity" : "",
            dfl & SERIO_TIMEOUT ? ", timeout" : "");
 
@@ -493,6 +386,58 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_RETVAL(ret);
 }
 
+/*
+ * i8042_enable_kbd_port enables keybaord port on chip
+ */
+
+static int i8042_enable_kbd_port(void)
+{
+       i8042_ctr &= ~I8042_CTR_KBDDIS;
+       i8042_ctr |= I8042_CTR_KBDINT;
+
+       if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
+               printk(KERN_ERR "i8042.c: Failed to enable KBD port.\n");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+/*
+ * i8042_enable_aux_port enables AUX (mouse) port on chip
+ */
+
+static int i8042_enable_aux_port(void)
+{
+       i8042_ctr &= ~I8042_CTR_AUXDIS;
+       i8042_ctr |= I8042_CTR_AUXINT;
+
+       if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
+               printk(KERN_ERR "i8042.c: Failed to enable AUX port.\n");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+/*
+ * i8042_enable_mux_ports enables 4 individual AUX ports after
+ * the controller has been switched into Multiplexed mode
+ */
+
+static int i8042_enable_mux_ports(void)
+{
+       unsigned char param;
+       int i;
+
+       for (i = 0; i < I8042_NUM_MUX_PORTS; i++) {
+               i8042_command(&param, I8042_CMD_MUX_PFX + i);
+               i8042_command(&param, I8042_CMD_AUX_ENABLE);
+       }
+
+       return i8042_enable_aux_port();
+}
+
 /*
  * i8042_set_mux_mode checks whether the controller has an active
  * multiplexor and puts the chip into Multiplexed (1) or Legacy (0) mode.
@@ -510,8 +455,7 @@ static int i8042_set_mux_mode(unsigned int mode, unsigned char *mux_version)
 
 /*
  * Internal loopback test - send three bytes, they should come back from the
- * mouse interface, the last should be version. Note that we negate mouseport
- * command responses for the i8042_check_aux() routine.
+ * mouse interface, the last should be version.
  */
 
        param = 0xf0;
@@ -530,67 +474,67 @@ static int i8042_set_mux_mode(unsigned int mode, unsigned char *mux_version)
        return 0;
 }
 
-
 /*
- * i8042_enable_mux_ports enables 4 individual AUX ports after
- * the controller has been switched into Multiplexed mode
+ * i8042_check_mux() checks whether the controller supports the PS/2 Active
+ * Multiplexing specification by Synaptics, Phoenix, Insyde and
+ * LCS/Telegraphics.
  */
 
-static int i8042_enable_mux_ports(void)
+static int __devinit i8042_check_mux(void)
 {
-       unsigned char param;
-       int i;
+       unsigned char mux_version;
+
+       if (i8042_set_mux_mode(1, &mux_version))
+               return -1;
+
 /*
- * Disable all muxed ports by disabling AUX.
+ * Workaround for interference with USB Legacy emulation
+ * that causes a v10.12 MUX to be found.
  */
+       if (mux_version == 0xAC)
+               return -1;
+
+       printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n",
+               (mux_version >> 4) & 0xf, mux_version & 0xf);
 
+/*
+ * Disable all muxed ports by disabling AUX.
+ */
        i8042_ctr |= I8042_CTR_AUXDIS;
        i8042_ctr &= ~I8042_CTR_AUXINT;
 
        if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
                printk(KERN_ERR "i8042.c: Failed to disable AUX port, can't use MUX.\n");
-               return -1;
+               return -EIO;
        }
 
-/*
- * Enable all muxed ports.
- */
-
-       for (i = 0; i < I8042_NUM_MUX_PORTS; i++) {
-               i8042_command(&param, I8042_CMD_MUX_PFX + i);
-               i8042_command(&param, I8042_CMD_AUX_ENABLE);
-       }
+       i8042_mux_present = 1;
 
        return 0;
 }
 
-
 /*
- * i8042_check_mux() checks whether the controller supports the PS/2 Active
- * Multiplexing specification by Synaptics, Phoenix, Insyde and
- * LCS/Telegraphics.
+ * The following is used to test AUX IRQ delivery.
  */
+static struct completion i8042_aux_irq_delivered __devinitdata;
+static int i8042_irq_being_tested __devinitdata;
 
-static int __devinit i8042_check_mux(void)
+static irqreturn_t __devinit i8042_aux_test_irq(int irq, void *dev_id, struct pt_regs *regs)
 {
-       unsigned char mux_version;
-
-       if (i8042_set_mux_mode(1, &mux_version))
-               return -1;
-
-       /* Workaround for interference with USB Legacy emulation */
-       /* that causes a v10.12 MUX to be found. */
-       if (mux_version == 0xAC)
-               return -1;
-
-       printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n",
-               (mux_version >> 4) & 0xf, mux_version & 0xf);
+       unsigned long flags;
+       unsigned char str, data;
 
-       if (i8042_enable_mux_ports())
-               return -1;
+       spin_lock_irqsave(&i8042_lock, flags);
+       str = i8042_read_status();
+       if (str & I8042_STR_OBF) {
+               data = i8042_read_data();
+               if (i8042_irq_being_tested &&
+                   data == 0xa5 && (str & I8042_STR_AUXDATA))
+                       complete(&i8042_aux_irq_delivered);
+       }
+       spin_unlock_irqrestore(&i8042_lock, flags);
 
-       i8042_mux_present = 1;
-       return 0;
+       return IRQ_HANDLED;
 }
 
 
@@ -601,18 +545,10 @@ static int __devinit i8042_check_mux(void)
 
 static int __devinit i8042_check_aux(void)
 {
+       int retval = -1;
+       int irq_registered = 0;
+       unsigned long flags;
        unsigned char param;
-       static int i8042_check_aux_cookie;
-
-/*
- * Check if AUX irq is available. If it isn't, then there is no point
- * in trying to detect AUX presence.
- */
-
-       if (request_irq(i8042_ports[I8042_AUX_PORT_NO].irq, i8042_interrupt,
-                       IRQF_SHARED, "i8042", &i8042_check_aux_cookie))
-                return -1;
-       free_irq(i8042_ports[I8042_AUX_PORT_NO].irq, &i8042_check_aux_cookie);
 
 /*
  * Get rid of bytes in the queue.
@@ -637,9 +573,9 @@ static int __devinit i8042_check_aux(void)
  * AUX ports, we test for this only when the LOOP command failed.
  */
 
-               if (i8042_command(&param, I8042_CMD_AUX_TEST)
-                       || (param && param != 0xfa && param != 0xff))
-                               return -1;
+               if (i8042_command(&param, I8042_CMD_AUX_TEST) ||
+                   (param && param != 0xfa && param != 0xff))
+                       return -1;
        }
 
 /*
@@ -659,54 +595,80 @@ static int __devinit i8042_check_aux(void)
                return -1;
 
 /*
- * Disable the interface.
+ * Test AUX IRQ delivery to make sure BIOS did not grab the IRQ and
+ * used it for a PCI card or somethig else.
  */
 
-       i8042_ctr |= I8042_CTR_AUXDIS;
-       i8042_ctr &= ~I8042_CTR_AUXINT;
+       if (i8042_noloop) {
+/*
+ * Without LOOP command we can't test AUX IRQ delivery. Assume the port
+ * is working and hope we are right.
+ */
+               retval = 0;
+               goto out;
+       }
 
-       if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR))
-               return -1;
+       if (request_irq(I8042_AUX_IRQ, i8042_aux_test_irq, IRQF_SHARED,
+                       "i8042", i8042_platform_device))
+               goto out;
 
-       return 0;
-}
+       irq_registered = 1;
+
+       if (i8042_enable_aux_port())
+               goto out;
+
+       spin_lock_irqsave(&i8042_lock, flags);
 
+       init_completion(&i8042_aux_irq_delivered);
+       i8042_irq_being_tested = 1;
+
+       param = 0xa5;
+       retval = __i8042_command(&param, I8042_CMD_AUX_LOOP & 0xf0ff);
+
+       spin_unlock_irqrestore(&i8042_lock, flags);
+
+       if (retval)
+               goto out;
 
+       if (wait_for_completion_timeout(&i8042_aux_irq_delivered,
+                                       msecs_to_jiffies(250)) == 0) {
 /*
- * i8042_port_register() marks the device as existing,
- * registers it, and reports to the user.
+ * AUX IRQ was never delivered so we need to flush the controller to
+ * get rid of the byte we put there; otherwise keyboard may not work.
  */
+               i8042_flush();
+               retval = -1;
+       }
 
-static int __devinit i8042_port_register(struct i8042_port *port)
-{
-       i8042_ctr &= ~port->disable;
+ out:
 
-       if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
-               printk(KERN_WARNING "i8042.c: Can't write CTR while registering.\n");
-               kfree(port->serio);
-               port->serio = NULL;
-               i8042_ctr |= port->disable;
-               return -EIO;
-       }
+/*
+ * Disable the interface.
+ */
 
-       printk(KERN_INFO "serio: i8042 %s port at %#lx,%#lx irq %d\n",
-              port->name,
-              (unsigned long) I8042_DATA_REG,
-              (unsigned long) I8042_COMMAND_REG,
-              port->irq);
+       i8042_ctr |= I8042_CTR_AUXDIS;
+       i8042_ctr &= ~I8042_CTR_AUXINT;
 
-       serio_register_port(port->serio);
+       if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR))
+               retval = -1;
 
-       return 0;
-}
+       if (irq_registered)
+               free_irq(I8042_AUX_IRQ, i8042_platform_device);
 
+       return retval;
+}
 
-static void i8042_timer_func(unsigned long data)
+static int i8042_controller_check(void)
 {
-       i8042_interrupt(0, NULL, NULL);
+       if (i8042_flush() == I8042_BUFFER_SIZE) {
+               printk(KERN_ERR "i8042.c: No controller found.\n");
+               return -ENODEV;
+       }
+
+       return 0;
 }
 
-static int i8042_ctl_test(void)
+static int i8042_controller_selftest(void)
 {
        unsigned char param;
 
@@ -715,13 +677,13 @@ static int i8042_ctl_test(void)
 
        if (i8042_command(&param, I8042_CMD_CTL_TEST)) {
                printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n");
-               return -1;
+               return -ENODEV;
        }
 
        if (param != I8042_RET_CTL_TEST) {
                printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n",
                         param, I8042_RET_CTL_TEST);
-               return -1;
+               return -EIO;
        }
 
        return 0;
@@ -737,26 +699,13 @@ static int i8042_controller_init(void)
 {
        unsigned long flags;
 
-/*
- * Test the i8042. We need to know if it thinks it's working correctly
- * before doing anything else.
- */
-
-       if (i8042_flush() == I8042_BUFFER_SIZE) {
-               printk(KERN_ERR "i8042.c: No controller found.\n");
-               return -1;
-       }
-
-       if (i8042_ctl_test())
-               return -1;
-
 /*
  * Save the CTR for restoral on unload / reboot.
  */
 
        if (i8042_command(&i8042_ctr, I8042_CMD_CTL_RCTR)) {
                printk(KERN_ERR "i8042.c: Can't read CTR while initializing i8042.\n");
-               return -1;
+               return -EIO;
        }
 
        i8042_initial_ctr = i8042_ctr;
@@ -805,7 +754,7 @@ static int i8042_controller_init(void)
 
        if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
                printk(KERN_ERR "i8042.c: Can't write CTR while initializing i8042.\n");
-               return -1;
+               return -EIO;
        }
 
        return 0;
@@ -813,15 +762,12 @@ static int i8042_controller_init(void)
 
 
 /*
- * Reset the controller.
+ * Reset the controller and reset CRT to the original value set by BIOS.
  */
+
 static void i8042_controller_reset(void)
 {
-/*
- * Reset the controller if requested.
- */
-
-       i8042_ctl_test();
+       i8042_flush();
 
 /*
  * Disable MUX mode if present.
@@ -831,12 +777,16 @@ static void i8042_controller_reset(void)
                i8042_set_mux_mode(0, NULL);
 
 /*
- * Restore the original control register setting.
+ * Reset the controller if requested.
  */
 
-       i8042_ctr = i8042_initial_ctr;
+       i8042_controller_selftest();
 
-       if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR))
+/*
+ * Restore the original control register setting.
+ */
+
+       if (i8042_command(&i8042_initial_ctr, I8042_CMD_CTL_WCTR))
                printk(KERN_WARNING "i8042.c: Can't restore CTR.\n");
 }
 
@@ -850,14 +800,12 @@ static void i8042_controller_cleanup(void)
 {
        int i;
 
-       i8042_flush();
-
 /*
  * Reset anything that is connected to the ports.
  */
 
        for (i = 0; i < I8042_NUM_PORTS; i++)
-               if (i8042_ports[i].exists)
+               if (i8042_ports[i].serio)
                        serio_cleanup(i8042_ports[i].serio);
 
        i8042_controller_reset();
@@ -913,8 +861,7 @@ static long i8042_panic_blink(long count)
 
 static int i8042_suspend(struct platform_device *dev, pm_message_t state)
 {
-       del_timer_sync(&i8042_timer);
-       i8042_controller_reset();
+       i8042_controller_cleanup();
 
        return 0;
 }
@@ -926,33 +873,39 @@ static int i8042_suspend(struct platform_device *dev, pm_message_t state)
 
 static int i8042_resume(struct platform_device *dev)
 {
-       int i;
+       int error;
 
-       if (i8042_ctl_test())
-               return -1;
+       error = i8042_controller_check();
+       if (error)
+               return error;
 
-       if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
-               printk(KERN_ERR "i8042: Can't write CTR\n");
-               return -1;
-       }
-
-       if (i8042_mux_present)
-               if (i8042_set_mux_mode(1, NULL) || i8042_enable_mux_ports())
-                       printk(KERN_WARNING "i8042: failed to resume active multiplexor, mouse won't work.\n");
+       error = i8042_controller_selftest();
+       if (error)
+               return error;
 
 /*
- * Activate all ports.
+ * Restore pre-resume CTR value and disable all ports
  */
 
-       for (i = 0; i < I8042_NUM_PORTS; i++)
-               i8042_activate_port(&i8042_ports[i]);
+       i8042_ctr |= I8042_CTR_AUXDIS | I8042_CTR_KBDDIS;
+       i8042_ctr &= ~(I8042_CTR_AUXINT | I8042_CTR_KBDINT);
+       if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
+               printk(KERN_ERR "i8042: Can't write CTR to resume\n");
+               return -EIO;
+       }
 
-/*
- * Restart timer (for polling "stuck" data)
- */
-       mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
+       if (i8042_mux_present) {
+               if (i8042_set_mux_mode(1, NULL) || i8042_enable_mux_ports())
+                       printk(KERN_WARNING
+                               "i8042: failed to resume active multiplexor, "
+                               "mouse won't work.\n");
+       } else if (i8042_ports[I8042_AUX_PORT_NO].serio)
+               i8042_enable_aux_port();
 
-       panic_blink = i8042_panic_blink;
+       if (i8042_ports[I8042_KBD_PORT_NO].serio)
+               i8042_enable_kbd_port();
+
+       i8042_interrupt(0, NULL, NULL);
 
        return 0;
 }
@@ -978,24 +931,24 @@ static int __devinit i8042_create_kbd_port(void)
 
        serio->id.type          = i8042_direct ? SERIO_8042 : SERIO_8042_XL;
        serio->write            = i8042_dumbkbd ? NULL : i8042_kbd_write;
-       serio->open             = i8042_open;
-       serio->close            = i8042_close;
        serio->start            = i8042_start;
        serio->stop             = i8042_stop;
        serio->port_data        = port;
        serio->dev.parent       = &i8042_platform_device->dev;
-       strlcpy(serio->name, "i8042 Kbd Port", sizeof(serio->name));
+       strlcpy(serio->name, "i8042 KBD port", sizeof(serio->name));
        strlcpy(serio->phys, I8042_KBD_PHYS_DESC, sizeof(serio->phys));
 
        port->serio = serio;
+       port->irq = I8042_KBD_IRQ;
 
-       return i8042_port_register(port);
+       return 0;
 }
 
-static int __devinit i8042_create_aux_port(void)
+static int __devinit i8042_create_aux_port(int idx)
 {
        struct serio *serio;
-       struct i8042_port *port = &i8042_ports[I8042_AUX_PORT_NO];
+       int port_no = idx < 0 ? I8042_AUX_PORT_NO : I8042_MUX_PORT_NO + idx;
+       struct i8042_port *port = &i8042_ports[port_no];
 
        serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
        if (!serio)
@@ -1003,111 +956,191 @@ static int __devinit i8042_create_aux_port(void)
 
        serio->id.type          = SERIO_8042;
        serio->write            = i8042_aux_write;
-       serio->open             = i8042_open;
-       serio->close            = i8042_close;
        serio->start            = i8042_start;
        serio->stop             = i8042_stop;
        serio->port_data        = port;
        serio->dev.parent       = &i8042_platform_device->dev;
-       strlcpy(serio->name, "i8042 Aux Port", sizeof(serio->name));
-       strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys));
+       if (idx < 0) {
+               strlcpy(serio->name, "i8042 AUX port", sizeof(serio->name));
+               strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys));
+       } else {
+               snprintf(serio->name, sizeof(serio->name), "i8042 AUX%d port", idx);
+               snprintf(serio->phys, sizeof(serio->phys), I8042_MUX_PHYS_DESC, idx + 1);
+       }
 
        port->serio = serio;
+       port->mux = idx;
+       port->irq = I8042_AUX_IRQ;
 
-       return i8042_port_register(port);
+       return 0;
 }
 
-static int __devinit i8042_create_mux_port(int index)
+static void __devinit i8042_free_kbd_port(void)
 {
-       struct serio *serio;
-       struct i8042_port *port = &i8042_ports[I8042_MUX_PORT_NO + index];
+       kfree(i8042_ports[I8042_KBD_PORT_NO].serio);
+       i8042_ports[I8042_KBD_PORT_NO].serio = NULL;
+}
 
-       serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
-       if (!serio)
-               return -ENOMEM;
+static void __devinit i8042_free_aux_ports(void)
+{
+       int i;
 
-       serio->id.type          = SERIO_8042;
-       serio->write            = i8042_aux_write;
-       serio->open             = i8042_open;
-       serio->close            = i8042_close;
-       serio->start            = i8042_start;
-       serio->stop             = i8042_stop;
-       serio->port_data        = port;
-       serio->dev.parent       = &i8042_platform_device->dev;
-       snprintf(serio->name, sizeof(serio->name), "i8042 Aux-%d Port", index);
-       snprintf(serio->phys, sizeof(serio->phys), I8042_MUX_PHYS_DESC, index + 1);
+       for (i = I8042_AUX_PORT_NO; i < I8042_NUM_PORTS; i++) {
+               kfree(i8042_ports[i].serio);
+               i8042_ports[i].serio = NULL;
+       }
+}
 
-       *port = i8042_ports[I8042_AUX_PORT_NO];
-       port->exists = 0;
-       snprintf(port->name, sizeof(port->name), "AUX%d", index);
-       port->mux = index;
-       port->serio = serio;
+static void __devinit i8042_register_ports(void)
+{
+       int i;
 
-       return i8042_port_register(port);
+       for (i = 0; i < I8042_NUM_PORTS; i++) {
+               if (i8042_ports[i].serio) {
+                       printk(KERN_INFO "serio: %s at %#lx,%#lx irq %d\n",
+                               i8042_ports[i].serio->name,
+                               (unsigned long) I8042_DATA_REG,
+                               (unsigned long) I8042_COMMAND_REG,
+                               i8042_ports[i].irq);
+                       serio_register_port(i8042_ports[i].serio);
+               }
+       }
 }
 
-static int __devinit i8042_probe(struct platform_device *dev)
+static void __devinit i8042_unregister_ports(void)
 {
-       int i, have_ports = 0;
-       int err;
+       int i;
 
-       init_timer(&i8042_timer);
-       i8042_timer.function = i8042_timer_func;
+       for (i = 0; i < I8042_NUM_PORTS; i++) {
+               if (i8042_ports[i].serio) {
+                       serio_unregister_port(i8042_ports[i].serio);
+                       i8042_ports[i].serio = NULL;
+               }
+       }
+}
+
+static void i8042_free_irqs(void)
+{
+       if (i8042_aux_irq_registered)
+               free_irq(I8042_AUX_IRQ, i8042_platform_device);
+       if (i8042_kbd_irq_registered)
+               free_irq(I8042_KBD_IRQ, i8042_platform_device);
+
+       i8042_aux_irq_registered = i8042_kbd_irq_registered = 0;
+}
+
+static int __devinit i8042_setup_aux(void)
+{
+       int (*aux_enable)(void);
+       int error;
+       int i;
 
-       if (i8042_controller_init())
+       if (i8042_check_aux())
                return -ENODEV;
 
-       if (!i8042_noaux && !i8042_check_aux()) {
-               if (!i8042_nomux && !i8042_check_mux()) {
-                       for (i = 0; i < I8042_NUM_MUX_PORTS; i++) {
-                               err = i8042_create_mux_port(i);
-                               if (err)
-                                       goto err_unregister_ports;
-                       }
-               } else {
-                       err = i8042_create_aux_port();
-                       if (err)
-                               goto err_unregister_ports;
+       if (i8042_nomux || i8042_check_mux()) {
+               error = i8042_create_aux_port(-1);
+               if (error)
+                       goto err_free_ports;
+               aux_enable = i8042_enable_aux_port;
+       } else {
+               for (i = 0; i < I8042_NUM_MUX_PORTS; i++) {
+                       error = i8042_create_aux_port(i);
+                       if (error)
+                               goto err_free_ports;
                }
-               have_ports = 1;
+               aux_enable = i8042_enable_mux_ports;
        }
 
-       if (!i8042_nokbd) {
-               err = i8042_create_kbd_port();
-               if (err)
-                       goto err_unregister_ports;
-               have_ports = 1;
-       }
+       error = request_irq(I8042_AUX_IRQ, i8042_interrupt, IRQF_SHARED,
+                           "i8042", i8042_platform_device);
+       if (error)
+               goto err_free_ports;
 
-       if (!have_ports) {
-               err = -ENODEV;
-               goto err_controller_cleanup;
-       }
+       if (aux_enable())
+               goto err_free_irq;
 
-       mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
+       i8042_aux_irq_registered = 1;
        return 0;
 
- err_unregister_ports:
-       for (i = 0; i < I8042_NUM_PORTS; i++)
-               if (i8042_ports[i].serio)
-                       serio_unregister_port(i8042_ports[i].serio);
- err_controller_cleanup:
-       i8042_controller_cleanup();
+ err_free_irq:
+       free_irq(I8042_AUX_IRQ, i8042_platform_device);
+ err_free_ports:
+       i8042_free_aux_ports();
+       return error;
+}
 
-       return err;
+static int __devinit i8042_setup_kbd(void)
+{
+       int error;
+
+       error = i8042_create_kbd_port();
+       if (error)
+               return error;
+
+       error = request_irq(I8042_KBD_IRQ, i8042_interrupt, IRQF_SHARED,
+                           "i8042", i8042_platform_device);
+       if (error)
+               goto err_free_port;
+
+       error = i8042_enable_kbd_port();
+       if (error)
+               goto err_free_irq;
+
+       i8042_kbd_irq_registered = 1;
+       return 0;
+
+ err_free_irq:
+       free_irq(I8042_KBD_IRQ, i8042_platform_device);
+ err_free_port:
+       i8042_free_kbd_port();
+       return error;
 }
 
-static int __devexit i8042_remove(struct platform_device *dev)
+static int __devinit i8042_probe(struct platform_device *dev)
 {
-       int i;
+       int error;
 
-       i8042_controller_cleanup();
+       error = i8042_controller_selftest();
+       if (error)
+               return error;
 
-       for (i = 0; i < I8042_NUM_PORTS; i++)
-               if (i8042_ports[i].exists)
-                       serio_unregister_port(i8042_ports[i].serio);
+       error = i8042_controller_init();
+       if (error)
+               return error;
+
+       if (!i8042_noaux) {
+               error = i8042_setup_aux();
+               if (error && error != -ENODEV && error != -EBUSY)
+                       goto out_fail;
+       }
+
+       if (!i8042_nokbd) {
+               error = i8042_setup_kbd();
+               if (error)
+                       goto out_fail;
+       }
 
-       del_timer_sync(&i8042_timer);
+/*
+ * Ok, everything is ready, let's register all serio ports
+ */
+       i8042_register_ports();
+
+       return 0;
+
+ out_fail:
+       i8042_free_aux_ports(); /* in case KBD failed but AUX not */
+       i8042_free_irqs();
+       i8042_controller_reset();
+
+       return error;
+}
+
+static int __devexit i8042_remove(struct platform_device *dev)
+{
+       i8042_unregister_ports();
+       i8042_free_irqs();
+       i8042_controller_reset();
 
        return 0;
 }
@@ -1134,8 +1167,9 @@ static int __init i8042_init(void)
        if (err)
                return err;
 
-       i8042_ports[I8042_AUX_PORT_NO].irq = I8042_AUX_IRQ;
-       i8042_ports[I8042_KBD_PORT_NO].irq = I8042_KBD_IRQ;
+       err = i8042_controller_check();
+       if (err)
+               goto err_platform_exit;
 
        err = platform_driver_register(&i8042_driver);
        if (err)
@@ -1151,6 +1185,8 @@ static int __init i8042_init(void)
        if (err)
                goto err_free_device;
 
+       panic_blink = i8042_panic_blink;
+
        return 0;
 
  err_free_device:
@@ -1167,7 +1203,6 @@ static void __exit i8042_exit(void)
 {
        platform_device_unregister(i8042_platform_device);
        platform_driver_unregister(&i8042_driver);
-
        i8042_platform_exit();
 
        panic_blink = NULL;
index af526ab9ec04205239f5d580aec7ce30323dc9e2..b3eb7a72d96114653799339dce4d9040391f4abd 100644 (file)
 
 #define I8042_CTL_TIMEOUT      10000
 
-/*
- * When the device isn't opened and it's interrupts aren't used, we poll it at
- * regular intervals to see if any characters arrived. If yes, we can start
- * probing for any mouse / keyboard connected. This is the period of the
- * polling.
- */
-
-#define I8042_POLL_PERIOD      HZ/20
-
 /*
  * Status register bits.
  */
index ed202f2f251aa76eeb3b680186a7baa7ddefaa7a..dcb16b5cbec084716050232f88c16fc53942b19f 100644 (file)
@@ -27,15 +27,6 @@ MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
 MODULE_DESCRIPTION("PS/2 driver library");
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(ps2_init);
-EXPORT_SYMBOL(ps2_sendbyte);
-EXPORT_SYMBOL(ps2_drain);
-EXPORT_SYMBOL(ps2_command);
-EXPORT_SYMBOL(ps2_schedule_command);
-EXPORT_SYMBOL(ps2_handle_ack);
-EXPORT_SYMBOL(ps2_handle_response);
-EXPORT_SYMBOL(ps2_cmd_aborted);
-
 /* Work structure to schedule execution of a command */
 struct ps2work {
        struct work_struct work;
@@ -71,6 +62,7 @@ int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout)
 
        return -ps2dev->nak;
 }
+EXPORT_SYMBOL(ps2_sendbyte);
 
 /*
  * ps2_drain() waits for device to transmit requested number of bytes
@@ -96,15 +88,16 @@ void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout)
                           msecs_to_jiffies(timeout));
        mutex_unlock(&ps2dev->cmd_mutex);
 }
+EXPORT_SYMBOL(ps2_drain);
 
 /*
  * ps2_is_keyboard_id() checks received ID byte against the list of
  * known keyboard IDs.
  */
 
-static inline int ps2_is_keyboard_id(char id_byte)
+int ps2_is_keyboard_id(char id_byte)
 {
-       static char keyboard_ids[] = {
+       const static char keyboard_ids[] = {
                0xab,   /* Regular keyboards            */
                0xac,   /* NCD Sun keyboard             */
                0x2b,   /* Trust keyboard, translated   */
@@ -115,6 +108,7 @@ static inline int ps2_is_keyboard_id(char id_byte)
 
        return memchr(keyboard_ids, id_byte, sizeof(keyboard_ids)) != NULL;
 }
+EXPORT_SYMBOL(ps2_is_keyboard_id);
 
 /*
  * ps2_adjust_timeout() is called after receiving 1st byte of command
@@ -138,6 +132,19 @@ static int ps2_adjust_timeout(struct ps2dev *ps2dev, int command, int timeout)
                        break;
 
                case PS2_CMD_GETID:
+                       /*
+                        * Microsoft Natural Elite keyboard responds to
+                        * the GET ID command as it were a mouse, with
+                        * a single byte. Fail the command so atkbd will
+                        * use alternative probe to detect it.
+                        */
+                       if (ps2dev->cmdbuf[1] == 0xaa) {
+                               serio_pause_rx(ps2dev->serio);
+                               ps2dev->flags = 0;
+                               serio_continue_rx(ps2dev->serio);
+                               timeout = 0;
+                       }
+
                        /*
                         * If device behind the port is not a keyboard there
                         * won't be 2nd byte of ID response.
@@ -237,6 +244,7 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
        mutex_unlock(&ps2dev->cmd_mutex);
        return rc;
 }
+EXPORT_SYMBOL(ps2_command);
 
 /*
  * ps2_execute_scheduled_command() sends a command, previously scheduled by
@@ -279,6 +287,7 @@ int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int comman
 
        return 0;
 }
+EXPORT_SYMBOL(ps2_schedule_command);
 
 /*
  * ps2_init() initializes ps2dev structure
@@ -290,6 +299,7 @@ void ps2_init(struct ps2dev *ps2dev, struct serio *serio)
        init_waitqueue_head(&ps2dev->wait);
        ps2dev->serio = serio;
 }
+EXPORT_SYMBOL(ps2_init);
 
 /*
  * ps2_handle_ack() is supposed to be used in interrupt handler
@@ -335,6 +345,7 @@ int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data)
 
        return 1;
 }
+EXPORT_SYMBOL(ps2_handle_ack);
 
 /*
  * ps2_handle_response() is supposed to be used in interrupt handler
@@ -360,6 +371,7 @@ int ps2_handle_response(struct ps2dev *ps2dev, unsigned char data)
 
        return 1;
 }
+EXPORT_SYMBOL(ps2_handle_response);
 
 void ps2_cmd_aborted(struct ps2dev *ps2dev)
 {
@@ -371,4 +383,4 @@ void ps2_cmd_aborted(struct ps2dev *ps2dev)
 
        ps2dev->flags = 0;
 }
-
+EXPORT_SYMBOL(ps2_cmd_aborted);
index b1b14f8d4dd6ecf8b6b5e1675cc7c67c7d7b4e6c..9418bbe4707298bc1d605fca696c7e03790b8f5d 100644 (file)
@@ -108,4 +108,40 @@ config TOUCHSCREEN_HP600
          To compile this driver as a module, choose M here: the
          module will be called hp680_ts_input.
 
+config TOUCHSCREEN_PENMOUNT
+       tristate "Penmount serial touchscreen"
+       select SERIO
+       help
+         Say Y here if you have a Penmount serial touchscreen connected to
+         your system.
+
+         If unsure, say N.
+
+         To compile this driver as a module, choose M here: the
+         module will be called penmount.
+
+config TOUCHSCREEN_TOUCHRIGHT
+       tristate "Touchright serial touchscreen"
+       select SERIO
+       help
+         Say Y here if you have a Touchright serial touchscreen connected to
+         your system.
+
+         If unsure, say N.
+
+         To compile this driver as a module, choose M here: the
+         module will be called touchright.
+
+config TOUCHSCREEN_TOUCHWIN
+       tristate "Touchwin serial touchscreen"
+       select SERIO
+       help
+         Say Y here if you have a Touchwin serial touchscreen connected to
+         your system.
+
+         If unsure, say N.
+
+         To compile this driver as a module, choose M here: the
+         module will be called touchwin.
+
 endif
index 5e5557c43121a128243412074d689c8340a5f2fd..1abb8f10d608809f5ecb57d4b0b1563cb3744bec 100644 (file)
@@ -12,3 +12,6 @@ obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o
 obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o
 obj-$(CONFIG_TOUCHSCREEN_MK712)        += mk712.o
 obj-$(CONFIG_TOUCHSCREEN_HP600)        += hp680_ts_input.o
+obj-$(CONFIG_TOUCHSCREEN_PENMOUNT)     += penmount.o
+obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT)   += touchright.o
+obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN)     += touchwin.o
index c86a2eb310fd93703f30246a7094d18a5529b64f..ab565335ee44131a69830fc9ac47b1213f58ce14 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/input.h>
 #include <linux/serio.h>
 #include <linux/init.h>
+#include <linux/ctype.h>
 
 #define DRIVER_DESC    "Elo serial touchscreen driver"
 
@@ -34,7 +35,19 @@ MODULE_LICENSE("GPL");
  * Definitions & global arrays.
  */
 
-#define        ELO_MAX_LENGTH  10
+#define ELO_MAX_LENGTH         10
+
+#define ELO10_PACKET_LEN       8
+#define ELO10_TOUCH            0x03
+#define ELO10_PRESSURE         0x80
+
+#define ELO10_LEAD_BYTE                'U'
+
+#define ELO10_ID_CMD           'i'
+
+#define ELO10_TOUCH_PACKET     'T'
+#define ELO10_ACK_PACKET       'A'
+#define ELI10_ID_PACKET                'I'
 
 /*
  * Per-touchscreen data.
@@ -43,51 +56,67 @@ MODULE_LICENSE("GPL");
 struct elo {
        struct input_dev *dev;
        struct serio *serio;
+       struct mutex cmd_mutex;
+       struct completion cmd_done;
        int id;
        int idx;
+       unsigned char expected_packet;
        unsigned char csum;
        unsigned char data[ELO_MAX_LENGTH];
+       unsigned char response[ELO10_PACKET_LEN];
        char phys[32];
 };
 
-static void elo_process_data_10(struct eloelo, unsigned char data, struct pt_regs *regs)
+static void elo_process_data_10(struct elo *elo, unsigned char data, struct pt_regs *regs)
 {
        struct input_dev *dev = elo->dev;
 
-       elo->csum += elo->data[elo->idx] = data;
-
+       elo->data[elo->idx] = data;
        switch (elo->idx++) {
-
                case 0:
-                       if (data != 'U') {
+                       elo->csum = 0xaa;
+                       if (data != ELO10_LEAD_BYTE) {
+                               pr_debug("elo: unsynchronized data: 0x%02x\n", data);
                                elo->idx = 0;
-                               elo->csum = 0;
-                       }
-                       break;
-
-               case 1:
-                       if (data != 'T') {
-                               elo->idx = 0;
-                               elo->csum = 0;
                        }
                        break;
 
                case 9:
-                       if (elo->csum) {
+                       elo->idx = 0;
+                       if (data != elo->csum) {
+                               pr_debug("elo: bad checksum: 0x%02x, expected 0x%02x\n",
+                                        data, elo->csum);
+                               break;
+                       }
+                       if (elo->data[1] != elo->expected_packet) {
+                               if (elo->data[1] != ELO10_TOUCH_PACKET)
+                                       pr_debug("elo: unexpected packet: 0x%02x\n",
+                                                elo->data[1]);
+                               break;
+                       }
+                       if (likely(elo->data[1] == ELO10_TOUCH_PACKET)) {
                                input_regs(dev, regs);
                                input_report_abs(dev, ABS_X, (elo->data[4] << 8) | elo->data[3]);
                                input_report_abs(dev, ABS_Y, (elo->data[6] << 8) | elo->data[5]);
-                               input_report_abs(dev, ABS_PRESSURE, (elo->data[8] << 8) | elo->data[7]);
-                               input_report_key(dev, BTN_TOUCH, elo->data[8] || elo->data[7]);
+                               if (elo->data[2] & ELO10_PRESSURE)
+                                       input_report_abs(dev, ABS_PRESSURE,
+                                                       (elo->data[8] << 8) | elo->data[7]);
+                               input_report_key(dev, BTN_TOUCH, elo->data[2] & ELO10_TOUCH);
                                input_sync(dev);
+                       } else if (elo->data[1] == ELO10_ACK_PACKET) {
+                               if (elo->data[2] == '0')
+                                       elo->expected_packet = ELO10_TOUCH_PACKET;
+                               complete(&elo->cmd_done);
+                       } else {
+                               memcpy(elo->response, &elo->data[1], ELO10_PACKET_LEN);
+                               elo->expected_packet = ELO10_ACK_PACKET;
                        }
-                       elo->idx = 0;
-                       elo->csum = 0;
                        break;
        }
+       elo->csum += data;
 }
 
-static void elo_process_data_6(struct eloelo, unsigned char data, struct pt_regs *regs)
+static void elo_process_data_6(struct elo *elo, unsigned char data, struct pt_regs *regs)
 {
        struct input_dev *dev = elo->dev;
 
@@ -135,7 +164,7 @@ static void elo_process_data_6(struct elo* elo, unsigned char data, struct pt_re
        }
 }
 
-static void elo_process_data_3(struct eloelo, unsigned char data, struct pt_regs *regs)
+static void elo_process_data_3(struct elo *elo, unsigned char data, struct pt_regs *regs)
 {
        struct input_dev *dev = elo->dev;
 
@@ -161,7 +190,7 @@ static void elo_process_data_3(struct elo* elo, unsigned char data, struct pt_re
 static irqreturn_t elo_interrupt(struct serio *serio,
                unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
-       struct eloelo = serio_get_drvdata(serio);
+       struct elo *elo = serio_get_drvdata(serio);
 
        switch(elo->id) {
                case 0:
@@ -181,17 +210,81 @@ static irqreturn_t elo_interrupt(struct serio *serio,
        return IRQ_HANDLED;
 }
 
+static int elo_command_10(struct elo *elo, unsigned char *packet)
+{
+       int rc = -1;
+       int i;
+       unsigned char csum = 0xaa + ELO10_LEAD_BYTE;
+
+       mutex_lock(&elo->cmd_mutex);
+
+       serio_pause_rx(elo->serio);
+       elo->expected_packet = toupper(packet[0]);
+       init_completion(&elo->cmd_done);
+       serio_continue_rx(elo->serio);
+
+       if (serio_write(elo->serio, ELO10_LEAD_BYTE))
+               goto out;
+
+       for (i = 0; i < ELO10_PACKET_LEN; i++) {
+               csum += packet[i];
+               if (serio_write(elo->serio, packet[i]))
+                       goto out;
+       }
+
+       if (serio_write(elo->serio, csum))
+               goto out;
+
+       wait_for_completion_timeout(&elo->cmd_done, HZ);
+
+       if (elo->expected_packet == ELO10_TOUCH_PACKET) {
+               /* We are back in reporting mode, the command was ACKed */
+               memcpy(packet, elo->response, ELO10_PACKET_LEN);
+               rc = 0;
+       }
+
+ out:
+       mutex_unlock(&elo->cmd_mutex);
+       return rc;
+}
+
+static int elo_setup_10(struct elo *elo)
+{
+       static const char *elo_types[] = { "Accu", "Dura", "Intelli", "Carroll" };
+       struct input_dev *dev = elo->dev;
+       unsigned char packet[ELO10_PACKET_LEN] = { ELO10_ID_CMD };
+
+       if (elo_command_10(elo, packet))
+               return -1;
+
+       dev->id.version = (packet[5] << 8) | packet[4];
+
+       input_set_abs_params(dev, ABS_X, 96, 4000, 0, 0);
+       input_set_abs_params(dev, ABS_Y, 96, 4000, 0, 0);
+       if (packet[3] & ELO10_PRESSURE)
+               input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
+
+       printk(KERN_INFO "elo: %sTouch touchscreen, fw: %02x.%02x, "
+               "features: %x02x, controller: 0x%02x\n",
+               elo_types[(packet[1] -'0') & 0x03],
+               packet[5], packet[4], packet[3], packet[7]);
+
+       return 0;
+}
+
 /*
  * elo_disconnect() is the opposite of elo_connect()
  */
 
 static void elo_disconnect(struct serio *serio)
 {
-       struct eloelo = serio_get_drvdata(serio);
+       struct elo *elo = serio_get_drvdata(serio);
 
+       input_get_device(elo->dev);
        input_unregister_device(elo->dev);
        serio_close(serio);
        serio_set_drvdata(serio, NULL);
+       input_put_device(elo->dev);
        kfree(elo);
 }
 
@@ -211,12 +304,15 @@ static int elo_connect(struct serio *serio, struct serio_driver *drv)
        input_dev = input_allocate_device();
        if (!elo || !input_dev) {
                err = -ENOMEM;
-               goto fail;
+               goto fail1;
        }
 
        elo->serio = serio;
        elo->id = serio->id.id;
        elo->dev = input_dev;
+       elo->expected_packet = ELO10_TOUCH_PACKET;
+       mutex_init(&elo->cmd_mutex);
+       init_completion(&elo->cmd_done);
        snprintf(elo->phys, sizeof(elo->phys), "%s/input0", serio->phys);
 
        input_dev->private = elo;
@@ -231,12 +327,17 @@ static int elo_connect(struct serio *serio, struct serio_driver *drv)
        input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
        input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
 
+       serio_set_drvdata(serio, elo);
+       err = serio_open(serio, drv);
+       if (err)
+               goto fail2;
+
        switch (elo->id) {
 
                case 0: /* 10-byte protocol */
-                       input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0);
-                       input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0);
-                       input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0);
+                       if (elo_setup_10(elo))
+                               goto fail3;
+
                        break;
 
                case 1: /* 6-byte protocol */
@@ -253,17 +354,15 @@ static int elo_connect(struct serio *serio, struct serio_driver *drv)
                        break;
        }
 
-       serio_set_drvdata(serio, elo);
-
-       err = serio_open(serio, drv);
+       err = input_register_device(elo->dev);
        if (err)
-               goto fail;
+               goto fail3;
 
-       input_register_device(elo->dev);
        return 0;
 
- fail: serio_set_drvdata(serio, NULL);
-       input_free_device(input_dev);
+ fail3: serio_close(serio);
+ fail2:        serio_set_drvdata(serio, NULL);
+ fail1:        input_free_device(input_dev);
        kfree(elo);
        return err;
 }
diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c
new file mode 100644 (file)
index 0000000..f737010
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * Penmount serial touchscreen driver
+ *
+ * Copyright (c) 2006 Rick Koch <n1gp@hotmail.com>
+ *
+ * Based on ELO driver (drivers/input/touchscreen/elo.c)
+ * Copyright (c) 2004 Vojtech Pavlik
+ */
+
+/*
+ * 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/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/init.h>
+
+#define DRIVER_DESC    "Penmount serial touchscreen driver"
+
+MODULE_AUTHOR("Rick Koch <n1gp@hotmail.com>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+/*
+ * Definitions & global arrays.
+ */
+
+#define        PM_MAX_LENGTH   5
+
+/*
+ * Per-touchscreen data.
+ */
+
+struct pm {
+       struct input_dev *dev;
+       struct serio *serio;
+       int idx;
+       unsigned char data[PM_MAX_LENGTH];
+       char phys[32];
+};
+
+static irqreturn_t pm_interrupt(struct serio *serio,
+               unsigned char data, unsigned int flags, struct pt_regs *regs)
+{
+       struct pm *pm = serio_get_drvdata(serio);
+       struct input_dev *dev = pm->dev;
+
+       pm->data[pm->idx] = data;
+
+       if (pm->data[0] & 0x80) {
+               if (PM_MAX_LENGTH == ++pm->idx) {
+                       input_regs(dev, regs);
+                       input_report_abs(dev, ABS_X, pm->data[2] * 128 + pm->data[1]);
+                       input_report_abs(dev, ABS_Y, pm->data[4] * 128 + pm->data[3]);
+                       input_report_key(dev, BTN_TOUCH, !!(pm->data[0] & 0x40));
+                       input_sync(dev);
+                       pm->idx = 0;
+               }
+       }
+
+       return IRQ_HANDLED;
+}
+
+/*
+ * pm_disconnect() is the opposite of pm_connect()
+ */
+
+static void pm_disconnect(struct serio *serio)
+{
+       struct pm *pm = serio_get_drvdata(serio);
+
+       input_get_device(pm->dev);
+       input_unregister_device(pm->dev);
+       serio_close(serio);
+       serio_set_drvdata(serio, NULL);
+       input_put_device(pm->dev);
+       kfree(pm);
+}
+
+/*
+ * pm_connect() is the routine that is called when someone adds a
+ * new serio device that supports Gunze protocol and registers it as
+ * an input device.
+ */
+
+static int pm_connect(struct serio *serio, struct serio_driver *drv)
+{
+       struct pm *pm;
+       struct input_dev *input_dev;
+       int err;
+
+       pm = kzalloc(sizeof(struct pm), GFP_KERNEL);
+       input_dev = input_allocate_device();
+       if (!pm || !input_dev) {
+               err = -ENOMEM;
+               goto fail1;
+       }
+
+       pm->serio = serio;
+       pm->dev = input_dev;
+       snprintf(pm->phys, sizeof(pm->phys), "%s/input0", serio->phys);
+
+       input_dev->private = pm;
+       input_dev->name = "Penmount Serial TouchScreen";
+       input_dev->phys = pm->phys;
+       input_dev->id.bustype = BUS_RS232;
+       input_dev->id.vendor = SERIO_PENMOUNT;
+       input_dev->id.product = 0;
+       input_dev->id.version = 0x0100;
+       input_dev->cdev.dev = &serio->dev;
+
+        input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+        input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+        input_set_abs_params(pm->dev, ABS_X, 0, 0x3ff, 0, 0);
+        input_set_abs_params(pm->dev, ABS_Y, 0, 0x3ff, 0, 0);
+
+       serio_set_drvdata(serio, pm);
+
+       err = serio_open(serio, drv);
+       if (err)
+               goto fail2;
+
+       err = input_register_device(pm->dev);
+       if (err)
+               goto fail3;
+
+       return 0;
+
+ fail3:        serio_close(serio);
+ fail2:        serio_set_drvdata(serio, NULL);
+ fail1:        input_free_device(input_dev);
+       kfree(pm);
+       return err;
+}
+
+/*
+ * The serio driver structure.
+ */
+
+static struct serio_device_id pm_serio_ids[] = {
+       {
+               .type   = SERIO_RS232,
+               .proto  = SERIO_PENMOUNT,
+               .id     = SERIO_ANY,
+               .extra  = SERIO_ANY,
+       },
+       { 0 }
+};
+
+MODULE_DEVICE_TABLE(serio, pm_serio_ids);
+
+static struct serio_driver pm_drv = {
+       .driver         = {
+               .name   = "penmountlpc",
+       },
+       .description    = DRIVER_DESC,
+       .id_table       = pm_serio_ids,
+       .interrupt      = pm_interrupt,
+       .connect        = pm_connect,
+       .disconnect     = pm_disconnect,
+};
+
+/*
+ * The functions for inserting/removing us as a module.
+ */
+
+static int __init pm_init(void)
+{
+       serio_register_driver(&pm_drv);
+       return 0;
+}
+
+static void __exit pm_exit(void)
+{
+       serio_unregister_driver(&pm_drv);
+}
+
+module_init(pm_init);
+module_exit(pm_exit);
diff --git a/drivers/input/touchscreen/touchright.c b/drivers/input/touchscreen/touchright.c
new file mode 100644 (file)
index 0000000..1c89fa5
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * Touchright serial touchscreen driver
+ *
+ * Copyright (c) 2006 Rick Koch <n1gp@hotmail.com>
+ *
+ * Based on MicroTouch driver (drivers/input/touchscreen/mtouch.c)
+ * Copyright (c) 2004 Vojtech Pavlik
+ * and Dan Streetman <ddstreet@ieee.org>
+ */
+
+/*
+ * 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/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/init.h>
+
+#define DRIVER_DESC    "Touchright serial touchscreen driver"
+
+MODULE_AUTHOR("Rick Koch <n1gp@hotmail.com>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+/*
+ * Definitions & global arrays.
+ */
+
+#define TR_FORMAT_TOUCH_BIT    0x01
+#define TR_FORMAT_STATUS_BYTE  0x40
+#define TR_FORMAT_STATUS_MASK  ~TR_FORMAT_TOUCH_BIT
+
+#define TR_LENGTH 5
+
+#define TR_MIN_XC 0
+#define TR_MAX_XC 0x1ff
+#define TR_MIN_YC 0
+#define TR_MAX_YC 0x1ff
+
+/*
+ * Per-touchscreen data.
+ */
+
+struct tr {
+       struct input_dev *dev;
+       struct serio *serio;
+       int idx;
+       unsigned char data[TR_LENGTH];
+       char phys[32];
+};
+
+static irqreturn_t tr_interrupt(struct serio *serio,
+               unsigned char data, unsigned int flags, struct pt_regs *regs)
+{
+       struct tr *tr = serio_get_drvdata(serio);
+       struct input_dev *dev = tr->dev;
+
+       tr->data[tr->idx] = data;
+
+       if ((tr->data[0] & TR_FORMAT_STATUS_MASK) == TR_FORMAT_STATUS_BYTE) {
+               if (++tr->idx == TR_LENGTH) {
+                       input_regs(dev, regs);
+                       input_report_abs(dev, ABS_X,
+                               (tr->data[1] << 5) | (tr->data[2] >> 1));
+                       input_report_abs(dev, ABS_Y,
+                               (tr->data[3] << 5) | (tr->data[4] >> 1));
+                       input_report_key(dev, BTN_TOUCH,
+                               tr->data[0] & TR_FORMAT_TOUCH_BIT);
+                       input_sync(dev);
+                       tr->idx = 0;
+               }
+       }
+
+       return IRQ_HANDLED;
+}
+
+/*
+ * tr_disconnect() is the opposite of tr_connect()
+ */
+
+static void tr_disconnect(struct serio *serio)
+{
+       struct tr *tr = serio_get_drvdata(serio);
+
+       input_get_device(tr->dev);
+       input_unregister_device(tr->dev);
+       serio_close(serio);
+       serio_set_drvdata(serio, NULL);
+       input_put_device(tr->dev);
+       kfree(tr);
+}
+
+/*
+ * tr_connect() is the routine that is called when someone adds a
+ * new serio device that supports the Touchright protocol and registers it as
+ * an input device.
+ */
+
+static int tr_connect(struct serio *serio, struct serio_driver *drv)
+{
+       struct tr *tr;
+       struct input_dev *input_dev;
+       int err;
+
+       tr = kzalloc(sizeof(struct tr), GFP_KERNEL);
+       input_dev = input_allocate_device();
+       if (!tr || !input_dev) {
+               err = -ENOMEM;
+               goto fail1;
+       }
+
+       tr->serio = serio;
+       tr->dev = input_dev;
+       snprintf(tr->phys, sizeof(tr->phys), "%s/input0", serio->phys);
+
+       input_dev->private = tr;
+       input_dev->name = "Touchright Serial TouchScreen";
+       input_dev->phys = tr->phys;
+       input_dev->id.bustype = BUS_RS232;
+       input_dev->id.vendor = SERIO_TOUCHRIGHT;
+       input_dev->id.product = 0;
+       input_dev->id.version = 0x0100;
+       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+       input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+       input_set_abs_params(tr->dev, ABS_X, TR_MIN_XC, TR_MAX_XC, 0, 0);
+       input_set_abs_params(tr->dev, ABS_Y, TR_MIN_YC, TR_MAX_YC, 0, 0);
+
+       serio_set_drvdata(serio, tr);
+
+       err = serio_open(serio, drv);
+       if (err)
+               goto fail2;
+
+       err = input_register_device(tr->dev);
+       if (err)
+               goto fail3;
+
+       return 0;
+
+ fail3:        serio_close(serio);
+ fail2:        serio_set_drvdata(serio, NULL);
+ fail1:        input_free_device(input_dev);
+       kfree(tr);
+       return err;
+}
+
+/*
+ * The serio driver structure.
+ */
+
+static struct serio_device_id tr_serio_ids[] = {
+       {
+               .type   = SERIO_RS232,
+               .proto  = SERIO_TOUCHRIGHT,
+               .id     = SERIO_ANY,
+               .extra  = SERIO_ANY,
+       },
+       { 0 }
+};
+
+MODULE_DEVICE_TABLE(serio, tr_serio_ids);
+
+static struct serio_driver tr_drv = {
+       .driver         = {
+               .name   = "touchright",
+       },
+       .description    = DRIVER_DESC,
+       .id_table       = tr_serio_ids,
+       .interrupt      = tr_interrupt,
+       .connect        = tr_connect,
+       .disconnect     = tr_disconnect,
+};
+
+/*
+ * The functions for inserting/removing us as a module.
+ */
+
+static int __init tr_init(void)
+{
+       serio_register_driver(&tr_drv);
+       return 0;
+}
+
+static void __exit tr_exit(void)
+{
+       serio_unregister_driver(&tr_drv);
+}
+
+module_init(tr_init);
+module_exit(tr_exit);
diff --git a/drivers/input/touchscreen/touchwin.c b/drivers/input/touchscreen/touchwin.c
new file mode 100644 (file)
index 0000000..a7b4c75
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * Touchwindow serial touchscreen driver
+ *
+ * Copyright (c) 2006 Rick Koch <n1gp@hotmail.com>
+ *
+ * Based on MicroTouch driver (drivers/input/touchscreen/mtouch.c)
+ * Copyright (c) 2004 Vojtech Pavlik
+ * and Dan Streetman <ddstreet@ieee.org>
+ */
+
+/*
+ * 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.
+ */
+
+/*
+ * 2005/02/19 Rick Koch:
+ *   The Touchwindow I used is made by Edmark Corp. and
+ *   constantly outputs a stream of 0's unless it is touched.
+ *   It then outputs 3 bytes: X, Y, and a copy of Y.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/init.h>
+
+#define DRIVER_DESC    "Touchwindow serial touchscreen driver"
+
+MODULE_AUTHOR("Rick Koch <n1gp@hotmail.com>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+/*
+ * Definitions & global arrays.
+ */
+
+#define TW_LENGTH 3
+
+#define TW_MIN_XC 0
+#define TW_MAX_XC 0xff
+#define TW_MIN_YC 0
+#define TW_MAX_YC 0xff
+
+/*
+ * Per-touchscreen data.
+ */
+
+struct tw {
+       struct input_dev *dev;
+       struct serio *serio;
+       int idx;
+       int touched;
+       unsigned char data[TW_LENGTH];
+       char phys[32];
+};
+
+static irqreturn_t tw_interrupt(struct serio *serio,
+               unsigned char data, unsigned int flags, struct pt_regs *regs)
+{
+       struct tw *tw = serio_get_drvdata(serio);
+       struct input_dev *dev = tw->dev;
+
+       if (data) {             /* touch */
+               tw->touched = 1;
+               tw->data[tw->idx++] = data;
+               /* verify length and that the two Y's are the same */
+               if (tw->idx == TW_LENGTH && tw->data[1] == tw->data[2]) {
+                       input_regs(dev, regs);
+                       input_report_abs(dev, ABS_X, tw->data[0]);
+                       input_report_abs(dev, ABS_Y, tw->data[1]);
+                       input_report_key(dev, BTN_TOUCH, 1);
+                       input_sync(dev);
+                       tw->idx = 0;
+               }
+       } else if (tw->touched) {       /* untouch */
+               input_report_key(dev, BTN_TOUCH, 0);
+               input_sync(dev);
+               tw->idx = 0;
+               tw->touched = 0;
+       }
+
+       return IRQ_HANDLED;
+}
+
+/*
+ * tw_disconnect() is the opposite of tw_connect()
+ */
+
+static void tw_disconnect(struct serio *serio)
+{
+       struct tw *tw = serio_get_drvdata(serio);
+
+       input_get_device(tw->dev);
+       input_unregister_device(tw->dev);
+       serio_close(serio);
+       serio_set_drvdata(serio, NULL);
+       input_put_device(tw->dev);
+       kfree(tw);
+}
+
+/*
+ * tw_connect() is the routine that is called when someone adds a
+ * new serio device that supports the Touchwin protocol and registers it as
+ * an input device.
+ */
+
+static int tw_connect(struct serio *serio, struct serio_driver *drv)
+{
+       struct tw *tw;
+       struct input_dev *input_dev;
+       int err;
+
+       tw = kzalloc(sizeof(struct tw), GFP_KERNEL);
+       input_dev = input_allocate_device();
+       if (!tw || !input_dev) {
+               err = -ENOMEM;
+               goto fail1;
+       }
+
+       tw->serio = serio;
+       tw->dev = input_dev;
+       snprintf(tw->phys, sizeof(tw->phys), "%s/input0", serio->phys);
+
+       input_dev->private = tw;
+       input_dev->name = "Touchwindow Serial TouchScreen";
+       input_dev->phys = tw->phys;
+       input_dev->id.bustype = BUS_RS232;
+       input_dev->id.vendor = SERIO_TOUCHWIN;
+       input_dev->id.product = 0;
+       input_dev->id.version = 0x0100;
+       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+       input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+       input_set_abs_params(tw->dev, ABS_X, TW_MIN_XC, TW_MAX_XC, 0, 0);
+       input_set_abs_params(tw->dev, ABS_Y, TW_MIN_YC, TW_MAX_YC, 0, 0);
+
+       serio_set_drvdata(serio, tw);
+
+       err = serio_open(serio, drv);
+       if (err)
+               goto fail2;
+
+       err = input_register_device(tw->dev);
+       if (err)
+               goto fail3;
+
+       return 0;
+
+ fail3:        serio_close(serio);
+ fail2:        serio_set_drvdata(serio, NULL);
+ fail1:        input_free_device(input_dev);
+       kfree(tw);
+       return err;
+}
+
+/*
+ * The serio driver structure.
+ */
+
+static struct serio_device_id tw_serio_ids[] = {
+       {
+               .type   = SERIO_RS232,
+               .proto  = SERIO_TOUCHWIN,
+               .id     = SERIO_ANY,
+               .extra  = SERIO_ANY,
+       },
+       { 0 }
+};
+
+MODULE_DEVICE_TABLE(serio, tw_serio_ids);
+
+static struct serio_driver tw_drv = {
+       .driver         = {
+               .name   = "touchwin",
+       },
+       .description    = DRIVER_DESC,
+       .id_table       = tw_serio_ids,
+       .interrupt      = tw_interrupt,
+       .connect        = tw_connect,
+       .disconnect     = tw_disconnect,
+};
+
+/*
+ * The functions for inserting/removing us as a module.
+ */
+
+static int __init tw_init(void)
+{
+       serio_register_driver(&tw_drv);
+       return 0;
+}
+
+static void __exit tw_exit(void)
+{
+       serio_unregister_driver(&tw_drv);
+}
+
+module_init(tw_init);
+module_exit(tw_exit);
index 00e3929c62888a906852558cf7935cf9b6c36022..a730c461227f78608d8c461195f33b80f11210fb 100644 (file)
@@ -135,8 +135,6 @@ struct tsdev_list {
 #define TS_GET_CAL     _IOR(IOC_H3600_TS_MAGIC, 10, struct ts_calibration)
 #define TS_SET_CAL     _IOW(IOC_H3600_TS_MAGIC, 11, struct ts_calibration)
 
-static struct input_handler tsdev_handler;
-
 static struct tsdev *tsdev_table[TSDEV_MINORS/2];
 
 static int tsdev_fasync(int fd, struct file *file, int on)
@@ -263,7 +261,7 @@ static int tsdev_ioctl(struct inode *inode, struct file *file,
        return retval;
 }
 
-static struct file_operations tsdev_fops = {
+static const struct file_operations tsdev_fops = {
        .owner =        THIS_MODULE,
        .open =         tsdev_open,
        .release =      tsdev_release,
@@ -370,7 +368,7 @@ static void tsdev_event(struct input_handle *handle, unsigned int type,
 
 static struct input_handle *tsdev_connect(struct input_handler *handler,
                                          struct input_dev *dev,
-                                         struct input_device_id *id)
+                                         const struct input_device_id *id)
 {
        struct tsdev *tsdev;
        struct class_device *cdev;
@@ -443,7 +441,7 @@ static void tsdev_disconnect(struct input_handle *handle)
                tsdev_free(tsdev);
 }
 
-static struct input_device_id tsdev_ids[] = {
+static const struct input_device_id tsdev_ids[] = {
        {
              .flags    = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_RELBIT,
              .evbit    = { BIT(EV_KEY) | BIT(EV_REL) },
@@ -481,9 +479,7 @@ static struct input_handler tsdev_handler = {
 
 static int __init tsdev_init(void)
 {
-       input_register_handler(&tsdev_handler);
-       printk(KERN_INFO "ts: Compaq touchscreen protocol output\n");
-       return 0;
+       return input_register_handler(&tsdev_handler);
 }
 
 static void __exit tsdev_exit(void)
index 669f76393b5a5128de344b0cc7b7b1cda40179e2..11844bbfe9339d3db64fc401347149edae459a69 100644 (file)
@@ -1298,7 +1298,7 @@ static int capinc_tty_read_proc(char *page, char **start, off_t off,
 
 static struct tty_driver *capinc_tty_driver;
 
-static struct tty_operations capinc_ops = {
+static const struct tty_operations capinc_ops = {
        .open = capinc_tty_open,
        .close = capinc_tty_close,
        .write = capinc_tty_write,
index bd2e4267528e58aadbcb4f770f75b4cccbc72ba0..596f3aebe2f7748c553aa50c860866aa8e37b205 100644 (file)
@@ -134,7 +134,7 @@ static int  if_tiocmset(struct tty_struct *tty, struct file *file,
 static int  if_write(struct tty_struct *tty,
                     const unsigned char *buf, int count);
 
-static struct tty_operations if_ops = {
+static const struct tty_operations if_ops = {
        .open =                 if_open,
        .close =                if_close,
        .ioctl =                if_ioctl,
index 9ae3a7f3e7b3724982ce68bc75a37ae215766a6a..9ad840e95dbe8247928b6191fcedcac8fe2ab63b 100644 (file)
@@ -83,5 +83,6 @@ void gigaset_init_dev_sysfs(struct cardstate *cs)
                return;
 
        gig_dbg(DEBUG_INIT, "setting up sysfs");
-       class_device_create_file(cs->class, &class_device_attr_cidmode);
+       if (class_device_create_file(cs->class, &class_device_attr_cidmode))
+               dev_err(cs->dev, "could not create sysfs attribute\n");
 }
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 e10350360f2ff27c5158fbebe732fa0991bf44bd..e4823ab2b12702b6085a48cec68ac1ad077c9dbc 100644 (file)
@@ -1721,11 +1721,11 @@ static void hisax_b_l1l2(struct hisax_if *ifc, int pr, void *arg)
                hisax_b_sched_event(bcs, B_RCVBUFREADY);
                break;
        case PH_DATA | CONFIRM:
-               bcs->tx_cnt -= (int) arg;
+               bcs->tx_cnt -= (long)arg;
                if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag)) {
                        u_long  flags;
                        spin_lock_irqsave(&bcs->aclock, flags);
-                       bcs->ackcnt += (int) arg;
+                       bcs->ackcnt += (long)arg;
                        spin_unlock_irqrestore(&bcs->aclock, flags);
                        schedule_event(bcs, B_ACKPENDING);
                }
@@ -1789,7 +1789,7 @@ static void hisax_b_l2l1(struct PStack *st, int pr, void *arg)
 
        switch (pr) {
        case PH_ACTIVATE | REQUEST:
-               B_L2L1(b_if, pr, (void *) st->l1.mode);
+               B_L2L1(b_if, pr, (void *)(unsigned long)st->l1.mode);
                break;
        case PH_DATA | REQUEST:
        case PH_PULL | INDICATION:
index 3a5ca8a68fc42fb512d64542aa707c819b5c997b..0ca5e66d2f5ab482fd78370ae29843cc4ce68d51 100644 (file)
@@ -424,7 +424,7 @@ bch_l2l1(struct hisax_if *ifc, int pr, void *arg)
        struct hfc4s8s_btype *bch = ifc->priv;
        struct hfc4s8s_l1 *l1 = bch->l1p;
        struct sk_buff *skb = (struct sk_buff *) arg;
-       int mode = (int) arg;
+       long mode = (long) arg;
        u_long flags;
 
        switch (pr) {
@@ -914,7 +914,7 @@ tx_d_frame(struct hfc4s8s_l1 *l1p)
        struct sk_buff *skb;
        u_char f1, f2;
        u_char *cp;
-       int cnt;
+       long cnt;
 
        if (l1p->l1_state != 7)
                return;
@@ -980,7 +980,8 @@ tx_b_frame(struct hfc4s8s_btype *bch)
        struct sk_buff *skb;
        struct hfc4s8s_l1 *l1 = bch->l1p;
        u_char *cp;
-       int cnt, max, hdlc_num, ack_len = 0;
+       int cnt, max, hdlc_num;
+       long ack_len = 0;
 
        if (!l1->enabled || (bch->mode == L1_MODE_NULL))
                return;
index f27c1608a3a706ba482d4163b0f67c2393e9dedd..b7e8e23be3371b7aa8f61d6dfd975cae26628379 100644 (file)
@@ -970,7 +970,7 @@ HFCSX_l1hw(struct PStack *st, int pr, void *arg)
                        break;
                case (HW_TESTLOOP | REQUEST):
                        spin_lock_irqsave(&cs->lock, flags);
-                       switch ((int) arg) {
+                       switch ((long) arg) {
                                case (1):
                                        Write_hfc(cs, HFCSX_B1_SSL, 0x80);      /* tx slot */
                                        Write_hfc(cs, HFCSX_B1_RSL, 0x80);      /* rx slot */
@@ -986,7 +986,7 @@ HFCSX_l1hw(struct PStack *st, int pr, void *arg)
                                default:
                                        spin_unlock_irqrestore(&cs->lock, flags);
                                        if (cs->debug & L1_DEB_WARN)
-                                               debugl1(cs, "hfcsx_l1hw loop invalid %4x", (int) arg);
+                                               debugl1(cs, "hfcsx_l1hw loop invalid %4lx", arg);
                                        return;
                        }
                        cs->hw.hfcsx.trm |= 0x80;       /* enable IOM-loop */
index b5e571a526943847f3bd1e0d0240d27c1041c989..6b88ecb5047dbf459de4de0a6f21f33cc640dd07 100644 (file)
@@ -696,7 +696,7 @@ tx_iso_complete(struct urb *urb, struct pt_regs *regs)
                                fifo->delete_flg = TRUE;
                                fifo->hif->l1l2(fifo->hif,
                                                PH_DATA | CONFIRM,
-                                               (void *) fifo->skbuff->
+                                               (void *) (unsigned long) fifo->skbuff->
                                                truesize);
                                if (fifo->skbuff && fifo->delete_flg) {
                                        dev_kfree_skb_any(fifo->skbuff);
@@ -1144,7 +1144,7 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg)
                                set_hfcmode(hfc,
                                            (fifo->fifonum ==
                                             HFCUSB_B1_TX) ? 0 : 1,
-                                           (int) arg);
+                                           (long) arg);
                                fifo->hif->l1l2(fifo->hif,
                                                PH_ACTIVATE | INDICATION,
                                                NULL);
index 75920aa0a3c57711514ec795a3084f003c46a527..2f9d5118ceaf8b1d545264a3dbab8d24415aa6d8 100644 (file)
@@ -1316,7 +1316,18 @@ void dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir);
 void iecpy(u_char * dest, u_char * iestart, int ieoffset);
 #endif /* __KERNEL__ */
 
-#define HZDELAY(jiffs) {int tout = jiffs; while (tout--) udelay(1000000/HZ);}
+/*
+ * Busywait delay for `jiffs' jiffies
+ */
+#define HZDELAY(jiffs) do {                                    \
+               int tout = jiffs;                               \
+                                                               \
+               while (tout--) {                                \
+                       int loops = USEC_PER_SEC / HZ;          \
+                       while (loops--)                         \
+                               udelay(1);                      \
+               }                                               \
+       } while (0)
 
 int ll_run(struct IsdnCardState *cs, int addfeatures);
 int CallcNew(void);
index 1d7cf3bd6aa336bbf1884869de15436efedcf57d..881a4165cfb47d8855b7a03d5d7af821a1f02602 100644 (file)
@@ -546,7 +546,7 @@ static inline void hdlc_xpr_irq(struct fritz_bcs *bcs)
        }
        bcs->tx_cnt = 0;
        bcs->tx_skb = NULL;
-       B_L1L2(bcs, PH_DATA | CONFIRM, (void *) skb->truesize);
+       B_L1L2(bcs, PH_DATA | CONFIRM, (void *)(unsigned long)skb->truesize);
        dev_kfree_skb_irq(skb);
 }
 
@@ -635,7 +635,7 @@ static void fritz_b_l2l1(struct hisax_if *ifc, int pr, void *arg)
                hdlc_fill_fifo(bcs);
                break;
        case PH_ACTIVATE | REQUEST:
-               mode = (int) arg;
+               mode = (long) arg;
                DBG(4,"B%d,PH_ACTIVATE_REQUEST %d", bcs->channel + 1, mode);
                modehdlc(bcs, mode);
                B_L1L2(bcs, PH_ACTIVATE | INDICATION, NULL);
@@ -998,18 +998,15 @@ static int __init hisax_fcpcipnp_init(void)
 
        retval = pci_register_driver(&fcpci_driver);
        if (retval)
-               goto out;
+               return retval;
 #ifdef __ISAPNP__
        retval = pnp_register_driver(&fcpnp_driver);
-       if (retval < 0)
-               goto out_unregister_pci;
+       if (retval < 0) {
+               pci_unregister_driver(&fcpci_driver);
+               return retval;
+       }
 #endif
        return 0;
-
- out_unregister_pci:
-       pci_unregister_driver(&fcpci_driver);
- out:
-       return retval;
 }
 
 static void __exit hisax_fcpcipnp_exit(void)
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 22fd5db18d48c613ab92245ec469408256a8120d..aca2a3954b1454dfd65a28036f0e06a3ff33879e 100644 (file)
@@ -86,7 +86,7 @@ static void usb_b_out(struct st5481_bcs *bcs,int buf_nr)
                        if (!skb->len) {
                                // Frame sent
                                b_out->tx_skb = NULL;
-                               B_L1L2(bcs, PH_DATA | CONFIRM, (void *) skb->truesize);
+                               B_L1L2(bcs, PH_DATA | CONFIRM, (void *)(unsigned long) skb->truesize);
                                dev_kfree_skb_any(skb);
 
 /*                             if (!(bcs->tx_skb = skb_dequeue(&bcs->sq))) { */
@@ -350,7 +350,7 @@ void st5481_b_l2l1(struct hisax_if *ifc, int pr, void *arg)
 {
        struct st5481_bcs *bcs = ifc->priv;
        struct sk_buff *skb = arg;
-       int mode;
+       long mode;
 
        DBG(4, "");
 
@@ -360,8 +360,8 @@ void st5481_b_l2l1(struct hisax_if *ifc, int pr, void *arg)
                bcs->b_out.tx_skb = skb;
                break;
        case PH_ACTIVATE | REQUEST:
-               mode = (int) arg;
-               DBG(4,"B%d,PH_ACTIVATE_REQUEST %d", bcs->channel + 1, mode);
+               mode = (long) arg;
+               DBG(4,"B%d,PH_ACTIVATE_REQUEST %ld", bcs->channel + 1, mode);
                st5481B_mode(bcs, mode);
                B_L1L2(bcs, PH_ACTIVATE | INDICATION, NULL);
                break;
index 493dc94992e568cc9f96627ebd3dd20a86931fa5..98adec4405906cffca26bf479927a69d40a7d440 100644 (file)
@@ -374,7 +374,7 @@ static void usb_d_out_complete(struct urb *urb, struct pt_regs *regs)
 {
        struct st5481_adapter *adapter = urb->context;
        struct st5481_d_out *d_out = &adapter->d_out;
-       int buf_nr;
+       long buf_nr;
        
        DBG(2, "");
 
@@ -546,7 +546,7 @@ static void dout_reseted(struct FsmInst *fsm, int event, void *arg)
 static void dout_complete(struct FsmInst *fsm, int event, void *arg)
 {
        struct st5481_adapter *adapter = fsm->userdata;
-       int buf_nr = (int) arg;
+       long buf_nr = (long) arg;
 
        usb_d_out(adapter, buf_nr);
 }
index 9ab66e8960d5ddc1082f5d23c5c86642c8c528c5..2b91bb07fc7f2ab087b80d501f772deca3f426ca 100644 (file)
@@ -1860,7 +1860,7 @@ modem_write_profile(atemu * m)
                send_sig(SIGIO, dev->profd, 1);
 }
 
-static struct tty_operations modem_ops = {
+static const struct tty_operations modem_ops = {
         .open = isdn_tty_open,
        .close = isdn_tty_close,
        .write = isdn_tty_write,
index b4b24335f7165b0e5de378a637ca98ab7697d702..04b8a58f03b55441420a1c16082293a740521742 100644 (file)
@@ -103,9 +103,6 @@ int command(isdn_ctrl *cmd)
                return -ENODEV;
        }
 
-       pr_debug("%s: Received %s command from Link Layer\n",
-               sc_adapter[card]->devicename, commands[cmd->command]);
-
        /*
         * Dispatch the command
         */
@@ -118,7 +115,7 @@ int command(isdn_ctrl *cmd)
                memcpy(&cmdptr, cmd->parm.num, sizeof(unsigned long));
                if (copy_from_user(&ioc, (scs_ioctl __user *)cmdptr,
                                   sizeof(scs_ioctl))) {
-                       pr_debug("%s: Failed to verify user space 0x%x\n",
+                       pr_debug("%s: Failed to verify user space 0x%lx\n",
                                sc_adapter[card]->devicename, cmdptr);
                        return -EFAULT;
                }
@@ -195,7 +192,7 @@ static int dial(int card, unsigned long channel, setup_parm setup)
                                strlen(Phone),
                                (unsigned int *) Phone);
 
-       pr_debug("%s: Dialing %s on channel %d\n",
+       pr_debug("%s: Dialing %s on channel %lu\n",
                sc_adapter[card]->devicename, Phone, channel+1);
        
        return status;
@@ -217,7 +214,7 @@ static int answer(int card, unsigned long channel)
        }
 
        indicate_status(card, ISDN_STAT_BCONN,channel,NULL);
-       pr_debug("%s: Answered incoming call on channel %s\n",
+       pr_debug("%s: Answered incoming call on channel %lu\n",
                sc_adapter[card]->devicename, channel+1);
        return 0;
 }
@@ -240,7 +237,7 @@ static int hangup(int card, unsigned long channel)
                                                 (unsigned char) channel+1,
                                                 0,
                                                 NULL);
-       pr_debug("%s: Sent HANGUP message to channel %d\n",
+       pr_debug("%s: Sent HANGUP message to channel %lu\n",
                sc_adapter[card]->devicename, channel+1);
        return status;
 }
@@ -260,9 +257,6 @@ static int setl2(int card, unsigned long arg)
        protocol = arg >> 8;
        channel = arg & 0xff;
        sc_adapter[card]->channel[channel].l2_proto = protocol;
-       pr_debug("%s: Level 2 protocol for channel %d set to %s from %d\n",
-               sc_adapter[card]->devicename, channel+1,
-               l2protos[sc_adapter[card]->channel[channel].l2_proto],protocol);
 
        /*
         * check that the adapter is also set to the correct protocol
@@ -293,8 +287,6 @@ static int setl3(int card, unsigned long channel)
        }
 
        sc_adapter[card]->channel[channel].l3_proto = protocol;
-       pr_debug("%s: Level 3 protocol for channel %d set to %s\n",
-               sc_adapter[card]->devicename, channel+1, l3protos[protocol]);
        return 0;
 }
 
@@ -311,7 +303,7 @@ static int acceptb(int card, unsigned long channel)
                return -ENOBUFS;
        }
 
-       pr_debug("%s: B-Channel connection accepted on channel %d\n",
+       pr_debug("%s: B-Channel connection accepted on channel %lu\n",
                sc_adapter[card]->devicename, channel+1);
        indicate_status(card, ISDN_STAT_BCONN, channel, NULL);
        return 0;
@@ -326,7 +318,7 @@ static int clreaz(int card, unsigned long arg)
 
        strcpy(sc_adapter[card]->channel[arg].eazlist, "");
        sc_adapter[card]->channel[arg].eazclear = 1;
-       pr_debug("%s: EAZ List cleared for channel %d\n",
+       pr_debug("%s: EAZ List cleared for channel %lu\n",
                sc_adapter[card]->devicename, arg+1);
        return 0;
 }
@@ -340,7 +332,7 @@ static int seteaz(int card, unsigned long arg, char *num)
 
        strcpy(sc_adapter[card]->channel[arg].eazlist, num);
        sc_adapter[card]->channel[arg].eazclear = 0;
-       pr_debug("%s: EAZ list for channel %d set to: %s\n",
+       pr_debug("%s: EAZ list for channel %lu set to: %s\n",
                sc_adapter[card]->devicename, arg+1,
                sc_adapter[card]->channel[arg].eazlist);
        return 0;
index 5b8c7c1a7663ffdc5418e8194a9a44430dd76279..57367325ef04513f9ef4fa30c81244c58cc41df6 100644 (file)
@@ -45,8 +45,10 @@ int indicate_status(int card, int event,ulong Channel,char *Data)
 {
        isdn_ctrl cmd;
 
+#ifdef DEBUG
        pr_debug("%s: Indicating event %s on Channel %d\n",
                sc_adapter[card]->devicename, events[event-256], Channel);
+#endif
        if (Data != NULL){
                pr_debug("%s: Event data: %s\n", sc_adapter[card]->devicename,
                        Data);
index 8631d338d69ab550084ad4e3d0eaaebacd206b6c..ae6263125ac2ef04dbcf8c4ff04c9af340a80ab9 100644 (file)
@@ -91,7 +91,7 @@ irqreturn_t interrupt_handler(int interrupt, void *cardptr, struct pt_regs *regs
                 */
                if (IS_CE_MESSAGE(rcvmsg, Lnk, 1, Read))
                {
-                       pr_debug("%s: Received packet 0x%x bytes long at 0x%x\n",
+                       pr_debug("%s: Received packet 0x%x bytes long at 0x%lx\n",
                                                sc_adapter[card]->devicename,
                                                rcvmsg.msg_data.response.msg_len,
                                                rcvmsg.msg_data.response.buff_offset);
index aced19aac5a2e5011d81cb4f03ef6805836e5d62..f43282be0adafd0e1b474ccea84cccb24ba9bc7f 100644 (file)
@@ -76,7 +76,7 @@ void check_reset(unsigned long data)
                if (sc_adapter[card]->StartOnReset)
                        startproc(card);
        } else  {
-               pr_debug("%s: No signature yet, waiting another %d jiffies.\n", 
+               pr_debug("%s: No signature yet, waiting another %lu jiffies.\n",
                        sc_adapter[card]->devicename, CHECKRESET_TIME);
                mod_timer(&sc_adapter[card]->reset_timer, jiffies+CHECKRESET_TIME);
                spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
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 80b89649e676a197fe941371f3fa64e5040d7a4a..4f04fd0956a006a5bb9097cc558912b2df77f4df 100644 (file)
@@ -336,8 +336,10 @@ int __init find_via_pmu(void)
                        if (gaddr != OF_BAD_ADDR)
                                gpio_reg = ioremap(gaddr, 0x10);
                }
-               if (gpio_reg == NULL)
+               if (gpio_reg == NULL) {
                        printk(KERN_ERR "via-pmu: Can't find GPIO reg !\n");
+                       goto fail_gpio;
+               }
        } else
                pmu_kind = PMU_UNKNOWN;
 
@@ -365,6 +367,9 @@ int __init find_via_pmu(void)
        return 1;
  fail:
        of_node_put(vias);
+       iounmap(gpio_reg);
+       gpio_reg = NULL;
+ fail_gpio:
        vias = NULL;
        return 0;
 }
index 6dd31a291d8436af9821d0b465866208daec3cd5..c92c1521546dfaa7c412f96ff9e021d5369b34ef 100644 (file)
@@ -138,16 +138,16 @@ config MD_RAID456
          If unsure, say Y.
 
 config MD_RAID5_RESHAPE
-       bool "Support adding drives to a raid-5 array (experimental)"
-       depends on MD_RAID456 && EXPERIMENTAL
+       bool "Support adding drives to a raid-5 array"
+       depends on MD_RAID456
+       default y
        ---help---
          A RAID-5 set can be expanded by adding extra drives. This
          requires "restriping" the array which means (almost) every
          block must be written to a different place.
 
           This option allows such restriping to be done while the array
-         is online.  However it is still EXPERIMENTAL code.  It should
-         work, but please be sure that you have backups.
+         is online.
 
          You will need mdadm version 2.4.1 or later to use this
          feature safely.  During the early stage of reshape there is
@@ -164,6 +164,8 @@ config MD_RAID5_RESHAPE
          There should be enough spares already present to make the new
          array workable.
 
+         If unsure, say Y.
+
 config MD_MULTIPATH
        tristate "Multipath I/O support"
        depends on BLK_DEV_MD
@@ -201,6 +203,14 @@ config BLK_DEV_DM
 
          If unsure, say N.
 
+config DM_DEBUG
+       boolean "Device mapper debugging support"
+       depends on BLK_DEV_DM && EXPERIMENTAL
+       ---help---
+         Enable this for messages that may help debug device-mapper problems.
+
+         If unsure, say N.
+
 config DM_CRYPT
        tristate "Crypt target support"
        depends on BLK_DEV_DM && EXPERIMENTAL
index ecc56765d949ebc977ebbe5326b0dcc39197566e..8e67634e79a0d1f16d033e9e7ecdf3bcdd416f56 100644 (file)
@@ -613,6 +613,7 @@ static inline unsigned long file_page_offset(unsigned long chunk)
 static inline struct page *filemap_get_page(struct bitmap *bitmap,
                                        unsigned long chunk)
 {
+       if (file_page_index(chunk) >= bitmap->file_pages) return NULL;
        return bitmap->filemap[file_page_index(chunk) - file_page_index(0)];
 }
 
@@ -739,6 +740,7 @@ static void bitmap_file_set_bit(struct bitmap *bitmap, sector_t block)
        }
 
        page = filemap_get_page(bitmap, chunk);
+       if (!page) return;
        bit = file_page_offset(chunk);
 
        /* set the bit */
@@ -1322,6 +1324,18 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int n
 
 }
 
+/* dirty the memory and file bits for bitmap chunks "s" to "e" */
+void bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e)
+{
+       unsigned long chunk;
+
+       for (chunk = s; chunk <= e; chunk++) {
+               sector_t sec = chunk << CHUNK_BLOCK_SHIFT(bitmap);
+               bitmap_set_memory_bits(bitmap, sec, 1);
+               bitmap_file_set_bit(bitmap, sec);
+       }
+}
+
 /*
  * flush out any pending updates
  */
@@ -1430,8 +1444,7 @@ int bitmap_create(mddev_t *mddev)
        if (err)
                goto error;
 
-       bitmap->chunkshift = find_first_bit(&bitmap->chunksize,
-                                       sizeof(bitmap->chunksize));
+       bitmap->chunkshift = ffz(~bitmap->chunksize);
 
        /* now that chunksize and chunkshift are set, we can use these macros */
        chunks = (blocks + CHUNK_BLOCK_RATIO(bitmap) - 1) /
index bdbd34993a80c055796804c1c0c8792ca99831bd..655d816760e591f0d007a6721fd557265004a791 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2003 Christophe Saout <christophe@saout.de>
  * Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org>
+ * Copyright (C) 2006 Red Hat, Inc. All rights reserved.
  *
  * This file is released under the GPL.
  */
 #include "dm.h"
 
 #define DM_MSG_PREFIX "crypt"
+#define MESG_STR(x) x, sizeof(x)
 
 /*
  * per bio private data
  */
 struct crypt_io {
        struct dm_target *target;
-       struct bio *bio;
+       struct bio *base_bio;
        struct bio *first_clone;
        struct work_struct work;
        atomic_t pending;
        int error;
+       int post_process;
 };
 
 /*
@@ -63,6 +66,7 @@ struct crypt_iv_operations {
  * Crypt: maps a linear range of a block device
  * and encrypts / decrypts at the same time.
  */
+enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID };
 struct crypt_config {
        struct dm_dev *dev;
        sector_t start;
@@ -73,6 +77,7 @@ struct crypt_config {
         */
        mempool_t *io_pool;
        mempool_t *page_pool;
+       struct bio_set *bs;
 
        /*
         * crypto related data
@@ -86,11 +91,12 @@ struct crypt_config {
        char cipher[CRYPTO_MAX_ALG_NAME];
        char chainmode[CRYPTO_MAX_ALG_NAME];
        struct crypto_blkcipher *tfm;
+       unsigned long flags;
        unsigned int key_size;
        u8 key[0];
 };
 
-#define MIN_IOS        256
+#define MIN_IOS        16
 #define MIN_POOL_PAGES 32
 #define MIN_BIO_PAGES  8
 
@@ -306,6 +312,14 @@ static int crypt_convert(struct crypt_config *cc,
        return r;
 }
 
+ static void dm_crypt_bio_destructor(struct bio *bio)
+ {
+       struct crypt_io *io = bio->bi_private;
+       struct crypt_config *cc = io->target->private;
+
+       bio_free(bio, cc->bs);
+ }
+
 /*
  * Generate a new unfragmented bio with the given size
  * This should never violate the device limitations
@@ -315,34 +329,33 @@ static struct bio *
 crypt_alloc_buffer(struct crypt_config *cc, unsigned int size,
                    struct bio *base_bio, unsigned int *bio_vec_idx)
 {
-       struct bio *bio;
+       struct bio *clone;
        unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
        gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM;
        unsigned int i;
 
-       /*
-        * Use __GFP_NOMEMALLOC to tell the VM to act less aggressively and
-        * to fail earlier.  This is not necessary but increases throughput.
-        * FIXME: Is this really intelligent?
-        */
-       if (base_bio)
-               bio = bio_clone(base_bio, GFP_NOIO|__GFP_NOMEMALLOC);
-       else
-               bio = bio_alloc(GFP_NOIO|__GFP_NOMEMALLOC, nr_iovecs);
-       if (!bio)
+       if (base_bio) {
+               clone = bio_alloc_bioset(GFP_NOIO, base_bio->bi_max_vecs, cc->bs);
+               __bio_clone(clone, base_bio);
+       } else
+               clone = bio_alloc_bioset(GFP_NOIO, nr_iovecs, cc->bs);
+
+       if (!clone)
                return NULL;
 
+       clone->bi_destructor = dm_crypt_bio_destructor;
+
        /* if the last bio was not complete, continue where that one ended */
-       bio->bi_idx = *bio_vec_idx;
-       bio->bi_vcnt = *bio_vec_idx;
-       bio->bi_size = 0;
-       bio->bi_flags &= ~(1 << BIO_SEG_VALID);
+       clone->bi_idx = *bio_vec_idx;
+       clone->bi_vcnt = *bio_vec_idx;
+       clone->bi_size = 0;
+       clone->bi_flags &= ~(1 << BIO_SEG_VALID);
 
-       /* bio->bi_idx pages have already been allocated */
-       size -= bio->bi_idx * PAGE_SIZE;
+       /* clone->bi_idx pages have already been allocated */
+       size -= clone->bi_idx * PAGE_SIZE;
 
-       for(i = bio->bi_idx; i < nr_iovecs; i++) {
-               struct bio_vec *bv = bio_iovec_idx(bio, i);
+       for (i = clone->bi_idx; i < nr_iovecs; i++) {
+               struct bio_vec *bv = bio_iovec_idx(clone, i);
 
                bv->bv_page = mempool_alloc(cc->page_pool, gfp_mask);
                if (!bv->bv_page)
@@ -353,7 +366,7 @@ crypt_alloc_buffer(struct crypt_config *cc, unsigned int size,
                 * return a partially allocated bio, the caller will then try
                 * to allocate additional bios while submitting this partial bio
                 */
-               if ((i - bio->bi_idx) == (MIN_BIO_PAGES - 1))
+               if ((i - clone->bi_idx) == (MIN_BIO_PAGES - 1))
                        gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT;
 
                bv->bv_offset = 0;
@@ -362,13 +375,13 @@ crypt_alloc_buffer(struct crypt_config *cc, unsigned int size,
                else
                        bv->bv_len = size;
 
-               bio->bi_size += bv->bv_len;
-               bio->bi_vcnt++;
+               clone->bi_size += bv->bv_len;
+               clone->bi_vcnt++;
                size -= bv->bv_len;
        }
 
-       if (!bio->bi_size) {
-               bio_put(bio);
+       if (!clone->bi_size) {
+               bio_put(clone);
                return NULL;
        }
 
@@ -376,13 +389,13 @@ crypt_alloc_buffer(struct crypt_config *cc, unsigned int size,
         * Remember the last bio_vec allocated to be able
         * to correctly continue after the splitting.
         */
-       *bio_vec_idx = bio->bi_vcnt;
+       *bio_vec_idx = clone->bi_vcnt;
 
-       return bio;
+       return clone;
 }
 
 static void crypt_free_buffer_pages(struct crypt_config *cc,
-                                    struct bio *bio, unsigned int bytes)
+                                    struct bio *clone, unsigned int bytes)
 {
        unsigned int i, start, end;
        struct bio_vec *bv;
@@ -396,19 +409,19 @@ static void crypt_free_buffer_pages(struct crypt_config *cc,
         * A fix to the bi_idx issue in the kernel is in the works, so
         * we will hopefully be able to revert to the cleaner solution soon.
         */
-       i = bio->bi_vcnt - 1;
-       bv = bio_iovec_idx(bio, i);
-       end = (i << PAGE_SHIFT) + (bv->bv_offset + bv->bv_len) - bio->bi_size;
+       i = clone->bi_vcnt - 1;
+       bv = bio_iovec_idx(clone, i);
+       end = (i << PAGE_SHIFT) + (bv->bv_offset + bv->bv_len) - clone->bi_size;
        start = end - bytes;
 
        start >>= PAGE_SHIFT;
-       if (!bio->bi_size)
-               end = bio->bi_vcnt;
+       if (!clone->bi_size)
+               end = clone->bi_vcnt;
        else
                end >>= PAGE_SHIFT;
 
-       for(i = start; i < end; i++) {
-               bv = bio_iovec_idx(bio, i);
+       for (i = start; i < end; i++) {
+               bv = bio_iovec_idx(clone, i);
                BUG_ON(!bv->bv_page);
                mempool_free(bv->bv_page, cc->page_pool);
                bv->bv_page = NULL;
@@ -432,7 +445,7 @@ static void dec_pending(struct crypt_io *io, int error)
        if (io->first_clone)
                bio_put(io->first_clone);
 
-       bio_endio(io->bio, io->bio->bi_size, io->error);
+       bio_endio(io->base_bio, io->base_bio->bi_size, io->error);
 
        mempool_free(io, cc->io_pool);
 }
@@ -441,29 +454,179 @@ static void dec_pending(struct crypt_io *io, int error)
  * kcryptd:
  *
  * Needed because it would be very unwise to do decryption in an
- * interrupt context, so bios returning from read requests get
- * queued here.
+ * interrupt context.
  */
 static struct workqueue_struct *_kcryptd_workqueue;
+static void kcryptd_do_work(void *data);
 
-static void kcryptd_do_work(void *data)
+static void kcryptd_queue_io(struct crypt_io *io)
 {
-       struct crypt_io *io = (struct crypt_io *) data;
-       struct crypt_config *cc = (struct crypt_config *) io->target->private;
+       INIT_WORK(&io->work, kcryptd_do_work, io);
+       queue_work(_kcryptd_workqueue, &io->work);
+}
+
+static int crypt_endio(struct bio *clone, unsigned int done, int error)
+{
+       struct crypt_io *io = clone->bi_private;
+       struct crypt_config *cc = io->target->private;
+       unsigned read_io = bio_data_dir(clone) == READ;
+
+       /*
+        * free the processed pages, even if
+        * it's only a partially completed write
+        */
+       if (!read_io)
+               crypt_free_buffer_pages(cc, clone, done);
+
+       /* keep going - not finished yet */
+       if (unlikely(clone->bi_size))
+               return 1;
+
+       if (!read_io)
+               goto out;
+
+       if (unlikely(!bio_flagged(clone, BIO_UPTODATE))) {
+               error = -EIO;
+               goto out;
+       }
+
+       bio_put(clone);
+       io->post_process = 1;
+       kcryptd_queue_io(io);
+       return 0;
+
+out:
+       bio_put(clone);
+       dec_pending(io, error);
+       return error;
+}
+
+static void clone_init(struct crypt_io *io, struct bio *clone)
+{
+       struct crypt_config *cc = io->target->private;
+
+       clone->bi_private = io;
+       clone->bi_end_io  = crypt_endio;
+       clone->bi_bdev    = cc->dev->bdev;
+       clone->bi_rw      = io->base_bio->bi_rw;
+}
+
+static void process_read(struct crypt_io *io)
+{
+       struct crypt_config *cc = io->target->private;
+       struct bio *base_bio = io->base_bio;
+       struct bio *clone;
+       sector_t sector = base_bio->bi_sector - io->target->begin;
+
+       atomic_inc(&io->pending);
+
+       /*
+        * The block layer might modify the bvec array, so always
+        * copy the required bvecs because we need the original
+        * one in order to decrypt the whole bio data *afterwards*.
+        */
+       clone = bio_alloc_bioset(GFP_NOIO, bio_segments(base_bio), cc->bs);
+       if (unlikely(!clone)) {
+               dec_pending(io, -ENOMEM);
+               return;
+       }
+
+       clone_init(io, clone);
+       clone->bi_destructor = dm_crypt_bio_destructor;
+       clone->bi_idx = 0;
+       clone->bi_vcnt = bio_segments(base_bio);
+       clone->bi_size = base_bio->bi_size;
+       clone->bi_sector = cc->start + sector;
+       memcpy(clone->bi_io_vec, bio_iovec(base_bio),
+              sizeof(struct bio_vec) * clone->bi_vcnt);
+
+       generic_make_request(clone);
+}
+
+static void process_write(struct crypt_io *io)
+{
+       struct crypt_config *cc = io->target->private;
+       struct bio *base_bio = io->base_bio;
+       struct bio *clone;
        struct convert_context ctx;
-       int r;
+       unsigned remaining = base_bio->bi_size;
+       sector_t sector = base_bio->bi_sector - io->target->begin;
+       unsigned bvec_idx = 0;
+
+       atomic_inc(&io->pending);
+
+       crypt_convert_init(cc, &ctx, NULL, base_bio, sector, 1);
+
+       /*
+        * The allocated buffers can be smaller than the whole bio,
+        * so repeat the whole process until all the data can be handled.
+        */
+       while (remaining) {
+               clone = crypt_alloc_buffer(cc, base_bio->bi_size,
+                                          io->first_clone, &bvec_idx);
+               if (unlikely(!clone)) {
+                       dec_pending(io, -ENOMEM);
+                       return;
+               }
+
+               ctx.bio_out = clone;
+
+               if (unlikely(crypt_convert(cc, &ctx) < 0)) {
+                       crypt_free_buffer_pages(cc, clone, clone->bi_size);
+                       bio_put(clone);
+                       dec_pending(io, -EIO);
+                       return;
+               }
+
+               clone_init(io, clone);
+               clone->bi_sector = cc->start + sector;
+
+               if (!io->first_clone) {
+                       /*
+                        * hold a reference to the first clone, because it
+                        * holds the bio_vec array and that can't be freed
+                        * before all other clones are released
+                        */
+                       bio_get(clone);
+                       io->first_clone = clone;
+               }
+
+               remaining -= clone->bi_size;
+               sector += bio_sectors(clone);
+
+               /* prevent bio_put of first_clone */
+               if (remaining)
+                       atomic_inc(&io->pending);
 
-       crypt_convert_init(cc, &ctx, io->bio, io->bio,
-                          io->bio->bi_sector - io->target->begin, 0);
-       r = crypt_convert(cc, &ctx);
+               generic_make_request(clone);
 
-       dec_pending(io, r);
+               /* out of memory -> run queues */
+               if (remaining)
+                       blk_congestion_wait(bio_data_dir(clone), HZ/100);
+       }
 }
 
-static void kcryptd_queue_io(struct crypt_io *io)
+static void process_read_endio(struct crypt_io *io)
 {
-       INIT_WORK(&io->work, kcryptd_do_work, io);
-       queue_work(_kcryptd_workqueue, &io->work);
+       struct crypt_config *cc = io->target->private;
+       struct convert_context ctx;
+
+       crypt_convert_init(cc, &ctx, io->base_bio, io->base_bio,
+                          io->base_bio->bi_sector - io->target->begin, 0);
+
+       dec_pending(io, crypt_convert(cc, &ctx));
+}
+
+static void kcryptd_do_work(void *data)
+{
+       struct crypt_io *io = data;
+
+       if (io->post_process)
+               process_read_endio(io);
+       else if (bio_data_dir(io->base_bio) == READ)
+               process_read(io);
+       else
+               process_write(io);
 }
 
 /*
@@ -477,7 +640,7 @@ static int crypt_decode_key(u8 *key, char *hex, unsigned int size)
 
        buffer[2] = '\0';
 
-       for(i = 0; i < size; i++) {
+       for (i = 0; i < size; i++) {
                buffer[0] = *hex++;
                buffer[1] = *hex++;
 
@@ -500,13 +663,38 @@ static void crypt_encode_key(char *hex, u8 *key, unsigned int size)
 {
        unsigned int i;
 
-       for(i = 0; i < size; i++) {
+       for (i = 0; i < size; i++) {
                sprintf(hex, "%02x", *key);
                hex += 2;
                key++;
        }
 }
 
+static int crypt_set_key(struct crypt_config *cc, char *key)
+{
+       unsigned key_size = strlen(key) >> 1;
+
+       if (cc->key_size && cc->key_size != key_size)
+               return -EINVAL;
+
+       cc->key_size = key_size; /* initial settings */
+
+       if ((!key_size && strcmp(key, "-")) ||
+           (key_size && crypt_decode_key(cc->key, key, key_size) < 0))
+               return -EINVAL;
+
+       set_bit(DM_CRYPT_KEY_VALID, &cc->flags);
+
+       return 0;
+}
+
+static int crypt_wipe_key(struct crypt_config *cc)
+{
+       clear_bit(DM_CRYPT_KEY_VALID, &cc->flags);
+       memset(&cc->key, 0, cc->key_size * sizeof(u8));
+       return 0;
+}
+
 /*
  * Construct an encryption mapping:
  * <cipher> <key> <iv_offset> <dev_path> <start>
@@ -539,16 +727,14 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 
        key_size = strlen(argv[1]) >> 1;
 
-       cc = kmalloc(sizeof(*cc) + key_size * sizeof(u8), GFP_KERNEL);
+       cc = kzalloc(sizeof(*cc) + key_size * sizeof(u8), GFP_KERNEL);
        if (cc == NULL) {
                ti->error =
                        "Cannot allocate transparent encryption context";
                return -ENOMEM;
        }
 
-       cc->key_size = key_size;
-       if ((!key_size && strcmp(argv[1], "-") != 0) ||
-           (key_size && crypt_decode_key(cc->key, argv[1], key_size) < 0)) {
+       if (crypt_set_key(cc, argv[1])) {
                ti->error = "Error decoding key";
                goto bad1;
        }
@@ -626,6 +812,12 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
                goto bad4;
        }
 
+       cc->bs = bioset_create(MIN_IOS, MIN_IOS, 4);
+       if (!cc->bs) {
+               ti->error = "Cannot allocate crypt bioset";
+               goto bad_bs;
+       }
+
        if (crypto_blkcipher_setkey(tfm, cc->key, key_size) < 0) {
                ti->error = "Error setting key";
                goto bad5;
@@ -665,6 +857,8 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        return 0;
 
 bad5:
+       bioset_free(cc->bs);
+bad_bs:
        mempool_destroy(cc->page_pool);
 bad4:
        mempool_destroy(cc->io_pool);
@@ -684,6 +878,7 @@ static void crypt_dtr(struct dm_target *ti)
 {
        struct crypt_config *cc = (struct crypt_config *) ti->private;
 
+       bioset_free(cc->bs);
        mempool_destroy(cc->page_pool);
        mempool_destroy(cc->io_pool);
 
@@ -698,147 +893,21 @@ static void crypt_dtr(struct dm_target *ti)
        kfree(cc);
 }
 
-static int crypt_endio(struct bio *bio, unsigned int done, int error)
-{
-       struct crypt_io *io = (struct crypt_io *) bio->bi_private;
-       struct crypt_config *cc = (struct crypt_config *) io->target->private;
-
-       if (bio_data_dir(bio) == WRITE) {
-               /*
-                * free the processed pages, even if
-                * it's only a partially completed write
-                */
-               crypt_free_buffer_pages(cc, bio, done);
-       }
-
-       if (bio->bi_size)
-               return 1;
-
-       bio_put(bio);
-
-       /*
-        * successful reads are decrypted by the worker thread
-        */
-       if ((bio_data_dir(bio) == READ)
-           && bio_flagged(bio, BIO_UPTODATE)) {
-               kcryptd_queue_io(io);
-               return 0;
-       }
-
-       dec_pending(io, error);
-       return error;
-}
-
-static inline struct bio *
-crypt_clone(struct crypt_config *cc, struct crypt_io *io, struct bio *bio,
-            sector_t sector, unsigned int *bvec_idx,
-            struct convert_context *ctx)
-{
-       struct bio *clone;
-
-       if (bio_data_dir(bio) == WRITE) {
-               clone = crypt_alloc_buffer(cc, bio->bi_size,
-                                 io->first_clone, bvec_idx);
-               if (clone) {
-                       ctx->bio_out = clone;
-                       if (crypt_convert(cc, ctx) < 0) {
-                               crypt_free_buffer_pages(cc, clone,
-                                                       clone->bi_size);
-                               bio_put(clone);
-                               return NULL;
-                       }
-               }
-       } else {
-               /*
-                * The block layer might modify the bvec array, so always
-                * copy the required bvecs because we need the original
-                * one in order to decrypt the whole bio data *afterwards*.
-                */
-               clone = bio_alloc(GFP_NOIO, bio_segments(bio));
-               if (clone) {
-                       clone->bi_idx = 0;
-                       clone->bi_vcnt = bio_segments(bio);
-                       clone->bi_size = bio->bi_size;
-                       memcpy(clone->bi_io_vec, bio_iovec(bio),
-                              sizeof(struct bio_vec) * clone->bi_vcnt);
-               }
-       }
-
-       if (!clone)
-               return NULL;
-
-       clone->bi_private = io;
-       clone->bi_end_io = crypt_endio;
-       clone->bi_bdev = cc->dev->bdev;
-       clone->bi_sector = cc->start + sector;
-       clone->bi_rw = bio->bi_rw;
-
-       return clone;
-}
-
 static int crypt_map(struct dm_target *ti, struct bio *bio,
                     union map_info *map_context)
 {
-       struct crypt_config *cc = (struct crypt_config *) ti->private;
-       struct crypt_io *io = mempool_alloc(cc->io_pool, GFP_NOIO);
-       struct convert_context ctx;
-       struct bio *clone;
-       unsigned int remaining = bio->bi_size;
-       sector_t sector = bio->bi_sector - ti->begin;
-       unsigned int bvec_idx = 0;
+       struct crypt_config *cc = ti->private;
+       struct crypt_io *io;
 
+       io = mempool_alloc(cc->io_pool, GFP_NOIO);
        io->target = ti;
-       io->bio = bio;
+       io->base_bio = bio;
        io->first_clone = NULL;
-       io->error = 0;
-       atomic_set(&io->pending, 1); /* hold a reference */
-
-       if (bio_data_dir(bio) == WRITE)
-               crypt_convert_init(cc, &ctx, NULL, bio, sector, 1);
-
-       /*
-        * The allocated buffers can be smaller than the whole bio,
-        * so repeat the whole process until all the data can be handled.
-        */
-       while (remaining) {
-               clone = crypt_clone(cc, io, bio, sector, &bvec_idx, &ctx);
-               if (!clone)
-                       goto cleanup;
-
-               if (!io->first_clone) {
-                       /*
-                        * hold a reference to the first clone, because it
-                        * holds the bio_vec array and that can't be freed
-                        * before all other clones are released
-                        */
-                       bio_get(clone);
-                       io->first_clone = clone;
-               }
-               atomic_inc(&io->pending);
+       io->error = io->post_process = 0;
+       atomic_set(&io->pending, 0);
+       kcryptd_queue_io(io);
 
-               remaining -= clone->bi_size;
-               sector += bio_sectors(clone);
-
-               generic_make_request(clone);
-
-               /* out of memory -> run queues */
-               if (remaining)
-                       blk_congestion_wait(bio_data_dir(clone), HZ/100);
-       }
-
-       /* drop reference, clones could have returned before we reach this */
-       dec_pending(io, 0);
        return 0;
-
-cleanup:
-       if (io->first_clone) {
-               dec_pending(io, -ENOMEM);
-               return 0;
-       }
-
-       /* if no bio has been dispatched yet, we can directly return the error */
-       mempool_free(io, cc->io_pool);
-       return -ENOMEM;
 }
 
 static int crypt_status(struct dm_target *ti, status_type_t type,
@@ -883,14 +952,71 @@ static int crypt_status(struct dm_target *ti, status_type_t type,
        return 0;
 }
 
+static void crypt_postsuspend(struct dm_target *ti)
+{
+       struct crypt_config *cc = ti->private;
+
+       set_bit(DM_CRYPT_SUSPENDED, &cc->flags);
+}
+
+static int crypt_preresume(struct dm_target *ti)
+{
+       struct crypt_config *cc = ti->private;
+
+       if (!test_bit(DM_CRYPT_KEY_VALID, &cc->flags)) {
+               DMERR("aborting resume - crypt key is not set.");
+               return -EAGAIN;
+       }
+
+       return 0;
+}
+
+static void crypt_resume(struct dm_target *ti)
+{
+       struct crypt_config *cc = ti->private;
+
+       clear_bit(DM_CRYPT_SUSPENDED, &cc->flags);
+}
+
+/* Message interface
+ *     key set <key>
+ *     key wipe
+ */
+static int crypt_message(struct dm_target *ti, unsigned argc, char **argv)
+{
+       struct crypt_config *cc = ti->private;
+
+       if (argc < 2)
+               goto error;
+
+       if (!strnicmp(argv[0], MESG_STR("key"))) {
+               if (!test_bit(DM_CRYPT_SUSPENDED, &cc->flags)) {
+                       DMWARN("not suspended during key manipulation.");
+                       return -EINVAL;
+               }
+               if (argc == 3 && !strnicmp(argv[1], MESG_STR("set")))
+                       return crypt_set_key(cc, argv[2]);
+               if (argc == 2 && !strnicmp(argv[1], MESG_STR("wipe")))
+                       return crypt_wipe_key(cc);
+       }
+
+error:
+       DMWARN("unrecognised message received.");
+       return -EINVAL;
+}
+
 static struct target_type crypt_target = {
        .name   = "crypt",
-       .version= {1, 1, 0},
+       .version= {1, 3, 0},
        .module = THIS_MODULE,
        .ctr    = crypt_ctr,
        .dtr    = crypt_dtr,
        .map    = crypt_map,
        .status = crypt_status,
+       .postsuspend = crypt_postsuspend,
+       .preresume = crypt_preresume,
+       .resume = crypt_resume,
+       .message = crypt_message,
 };
 
 static int __init dm_crypt_init(void)
index d12379b5cdb5137da258453bf6729cc1f44d49af..99cdffa7fbfe0a4522330099dd80ca810f3dc796 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/slab.h>
 
 #define DM_MSG_PREFIX "snapshots"
+#define DM_CHUNK_SIZE_DEFAULT_SECTORS 32       /* 16KB */
 
 /*-----------------------------------------------------------------
  * Persistent snapshots, by persistent we mean that the snapshot
@@ -150,6 +151,7 @@ static int alloc_area(struct pstore *ps)
 static void free_area(struct pstore *ps)
 {
        vfree(ps->area);
+       ps->area = NULL;
 }
 
 /*
@@ -198,48 +200,79 @@ static int read_header(struct pstore *ps, int *new_snapshot)
        int r;
        struct disk_header *dh;
        chunk_t chunk_size;
+       int chunk_size_supplied = 1;
 
-       r = chunk_io(ps, 0, READ);
+       /*
+        * Use default chunk size (or hardsect_size, if larger) if none supplied
+        */
+       if (!ps->snap->chunk_size) {
+               ps->snap->chunk_size = max(DM_CHUNK_SIZE_DEFAULT_SECTORS,
+                   bdev_hardsect_size(ps->snap->cow->bdev) >> 9);
+               ps->snap->chunk_mask = ps->snap->chunk_size - 1;
+               ps->snap->chunk_shift = ffs(ps->snap->chunk_size) - 1;
+               chunk_size_supplied = 0;
+       }
+
+       r = dm_io_get(sectors_to_pages(ps->snap->chunk_size));
        if (r)
                return r;
 
+       r = alloc_area(ps);
+       if (r)
+               goto bad1;
+
+       r = chunk_io(ps, 0, READ);
+       if (r)
+               goto bad2;
+
        dh = (struct disk_header *) ps->area;
 
        if (le32_to_cpu(dh->magic) == 0) {
                *new_snapshot = 1;
+               return 0;
+       }
 
-       } else if (le32_to_cpu(dh->magic) == SNAP_MAGIC) {
-               *new_snapshot = 0;
-               ps->valid = le32_to_cpu(dh->valid);
-               ps->version = le32_to_cpu(dh->version);
-               chunk_size = le32_to_cpu(dh->chunk_size);
-               if (ps->snap->chunk_size != chunk_size) {
-                       DMWARN("chunk size %llu in device metadata overrides "
-                              "table chunk size of %llu.",
-                              (unsigned long long)chunk_size,
-                              (unsigned long long)ps->snap->chunk_size);
-
-                       /* We had a bogus chunk_size. Fix stuff up. */
-                       dm_io_put(sectors_to_pages(ps->snap->chunk_size));
-                       free_area(ps);
-
-                       ps->snap->chunk_size = chunk_size;
-                       ps->snap->chunk_mask = chunk_size - 1;
-                       ps->snap->chunk_shift = ffs(chunk_size) - 1;
-
-                       r = alloc_area(ps);
-                       if (r)
-                               return r;
-
-                       r = dm_io_get(sectors_to_pages(chunk_size));
-                       if (r)
-                               return r;
-               }
-       } else {
-               DMWARN("Invalid/corrupt snapshot");
+       if (le32_to_cpu(dh->magic) != SNAP_MAGIC) {
+               DMWARN("Invalid or corrupt snapshot");
                r = -ENXIO;
+               goto bad2;
        }
 
+       *new_snapshot = 0;
+       ps->valid = le32_to_cpu(dh->valid);
+       ps->version = le32_to_cpu(dh->version);
+       chunk_size = le32_to_cpu(dh->chunk_size);
+
+       if (!chunk_size_supplied || ps->snap->chunk_size == chunk_size)
+               return 0;
+
+       DMWARN("chunk size %llu in device metadata overrides "
+              "table chunk size of %llu.",
+              (unsigned long long)chunk_size,
+              (unsigned long long)ps->snap->chunk_size);
+
+       /* We had a bogus chunk_size. Fix stuff up. */
+       dm_io_put(sectors_to_pages(ps->snap->chunk_size));
+       free_area(ps);
+
+       ps->snap->chunk_size = chunk_size;
+       ps->snap->chunk_mask = chunk_size - 1;
+       ps->snap->chunk_shift = ffs(chunk_size) - 1;
+
+       r = dm_io_get(sectors_to_pages(chunk_size));
+       if (r)
+               return r;
+
+       r = alloc_area(ps);
+       if (r)
+               goto bad1;
+
+       return 0;
+
+bad2:
+       free_area(ps);
+bad1:
+       dm_io_put(sectors_to_pages(ps->snap->chunk_size));
        return r;
 }
 
@@ -263,42 +296,29 @@ static int write_header(struct pstore *ps)
  */
 static struct disk_exception *get_exception(struct pstore *ps, uint32_t index)
 {
-       if (index >= ps->exceptions_per_area)
-               return NULL;
+       BUG_ON(index >= ps->exceptions_per_area);
 
        return ((struct disk_exception *) ps->area) + index;
 }
 
-static int read_exception(struct pstore *ps,
-                         uint32_t index, struct disk_exception *result)
+static void read_exception(struct pstore *ps,
+                          uint32_t index, struct disk_exception *result)
 {
-       struct disk_exception *e;
-
-       e = get_exception(ps, index);
-       if (!e)
-               return -EINVAL;
+       struct disk_exception *e = get_exception(ps, index);
 
        /* copy it */
        result->old_chunk = le64_to_cpu(e->old_chunk);
        result->new_chunk = le64_to_cpu(e->new_chunk);
-
-       return 0;
 }
 
-static int write_exception(struct pstore *ps,
-                          uint32_t index, struct disk_exception *de)
+static void write_exception(struct pstore *ps,
+                           uint32_t index, struct disk_exception *de)
 {
-       struct disk_exception *e;
-
-       e = get_exception(ps, index);
-       if (!e)
-               return -EINVAL;
+       struct disk_exception *e = get_exception(ps, index);
 
        /* copy it */
        e->old_chunk = cpu_to_le64(de->old_chunk);
        e->new_chunk = cpu_to_le64(de->new_chunk);
-
-       return 0;
 }
 
 /*
@@ -316,10 +336,7 @@ static int insert_exceptions(struct pstore *ps, int *full)
        *full = 1;
 
        for (i = 0; i < ps->exceptions_per_area; i++) {
-               r = read_exception(ps, i, &de);
-
-               if (r)
-                       return r;
+               read_exception(ps, i, &de);
 
                /*
                 * If the new_chunk is pointing at the start of
@@ -519,6 +536,16 @@ static void persistent_commit(struct exception_store *store,
                if (r)
                        ps->valid = 0;
 
+               /*
+                * Have we completely filled the current area ?
+                */
+               if (ps->current_committed == ps->exceptions_per_area) {
+                       ps->current_committed = 0;
+                       r = zero_area(ps, ps->current_area + 1);
+                       if (r)
+                               ps->valid = 0;
+               }
+
                for (i = 0; i < ps->callback_count; i++) {
                        cb = ps->callbacks + i;
                        cb->callback(cb->context, r == 0 ? 1 : 0);
@@ -526,16 +553,6 @@ static void persistent_commit(struct exception_store *store,
 
                ps->callback_count = 0;
        }
-
-       /*
-        * Have we completely filled the current area ?
-        */
-       if (ps->current_committed == ps->exceptions_per_area) {
-               ps->current_committed = 0;
-               r = zero_area(ps, ps->current_area + 1);
-               if (r)
-                       ps->valid = 0;
-       }
 }
 
 static void persistent_drop(struct exception_store *store)
@@ -547,32 +564,22 @@ static void persistent_drop(struct exception_store *store)
                DMWARN("write header failed");
 }
 
-int dm_create_persistent(struct exception_store *store, uint32_t chunk_size)
+int dm_create_persistent(struct exception_store *store)
 {
-       int r;
        struct pstore *ps;
 
-       r = dm_io_get(sectors_to_pages(chunk_size));
-       if (r)
-               return r;
-
        /* allocate the pstore */
        ps = kmalloc(sizeof(*ps), GFP_KERNEL);
-       if (!ps) {
-               r = -ENOMEM;
-               goto bad;
-       }
+       if (!ps)
+               return -ENOMEM;
 
        ps->snap = store->snap;
        ps->valid = 1;
        ps->version = SNAPSHOT_DISK_VERSION;
+       ps->area = NULL;
        ps->next_free = 2;      /* skipping the header and first area */
        ps->current_committed = 0;
 
-       r = alloc_area(ps);
-       if (r)
-               goto bad;
-
        ps->callback_count = 0;
        atomic_set(&ps->pending_count, 0);
        ps->callbacks = NULL;
@@ -586,13 +593,6 @@ int dm_create_persistent(struct exception_store *store, uint32_t chunk_size)
        store->context = ps;
 
        return 0;
-
-      bad:
-       dm_io_put(sectors_to_pages(chunk_size));
-       if (ps && ps->area)
-               free_area(ps);
-       kfree(ps);
-       return r;
 }
 
 /*-----------------------------------------------------------------
@@ -642,18 +642,16 @@ static void transient_fraction_full(struct exception_store *store,
        *denominator = get_dev_size(store->snap->cow->bdev);
 }
 
-int dm_create_transient(struct exception_store *store,
-                       struct dm_snapshot *s, int blocksize)
+int dm_create_transient(struct exception_store *store)
 {
        struct transient_c *tc;
 
-       memset(store, 0, sizeof(*store));
        store->destroy = transient_destroy;
        store->read_metadata = transient_read_metadata;
        store->prepare_exception = transient_prepare;
        store->commit_exception = transient_commit;
+       store->drop_snapshot = NULL;
        store->fraction_full = transient_fraction_full;
-       store->snap = s;
 
        tc = kmalloc(sizeof(struct transient_c), GFP_KERNEL);
        if (!tc)
index 47b3c62bbdb8839086466a60439a0651758acd52..00234909b3db02b8b55e146b09fe27f57a20cdcc 100644 (file)
@@ -98,14 +98,31 @@ static int linear_status(struct dm_target *ti, status_type_t type,
        return 0;
 }
 
+static int linear_ioctl(struct dm_target *ti, struct inode *inode,
+                       struct file *filp, unsigned int cmd,
+                       unsigned long arg)
+{
+       struct linear_c *lc = (struct linear_c *) ti->private;
+       struct block_device *bdev = lc->dev->bdev;
+       struct file fake_file = {};
+       struct dentry fake_dentry = {};
+
+       fake_file.f_mode = lc->dev->mode;
+       fake_file.f_dentry = &fake_dentry;
+       fake_dentry.d_inode = bdev->bd_inode;
+
+       return blkdev_driver_ioctl(bdev->bd_inode, &fake_file, bdev->bd_disk, cmd, arg);
+}
+
 static struct target_type linear_target = {
        .name   = "linear",
-       .version= {1, 0, 1},
+       .version= {1, 0, 2},
        .module = THIS_MODULE,
        .ctr    = linear_ctr,
        .dtr    = linear_dtr,
        .map    = linear_map,
        .status = linear_status,
+       .ioctl  = linear_ioctl,
 };
 
 int __init dm_linear_init(void)
index 93f701ea87bc3438bf5ab2426b74e5f43085827a..d754e0bc6e90c09f8ea73311e509e3d0a88f707d 100644 (file)
@@ -114,12 +114,10 @@ static void trigger_event(void *data);
 
 static struct pgpath *alloc_pgpath(void)
 {
-       struct pgpath *pgpath = kmalloc(sizeof(*pgpath), GFP_KERNEL);
+       struct pgpath *pgpath = kzalloc(sizeof(*pgpath), GFP_KERNEL);
 
-       if (pgpath) {
-               memset(pgpath, 0, sizeof(*pgpath));
+       if (pgpath)
                pgpath->path.is_active = 1;
-       }
 
        return pgpath;
 }
@@ -133,12 +131,10 @@ static struct priority_group *alloc_priority_group(void)
 {
        struct priority_group *pg;
 
-       pg = kmalloc(sizeof(*pg), GFP_KERNEL);
-       if (!pg)
-               return NULL;
+       pg = kzalloc(sizeof(*pg), GFP_KERNEL);
 
-       memset(pg, 0, sizeof(*pg));
-       INIT_LIST_HEAD(&pg->pgpaths);
+       if (pg)
+               INIT_LIST_HEAD(&pg->pgpaths);
 
        return pg;
 }
@@ -168,13 +164,12 @@ static void free_priority_group(struct priority_group *pg,
        kfree(pg);
 }
 
-static struct multipath *alloc_multipath(void)
+static struct multipath *alloc_multipath(struct dm_target *ti)
 {
        struct multipath *m;
 
-       m = kmalloc(sizeof(*m), GFP_KERNEL);
+       m = kzalloc(sizeof(*m), GFP_KERNEL);
        if (m) {
-               memset(m, 0, sizeof(*m));
                INIT_LIST_HEAD(&m->priority_groups);
                spin_lock_init(&m->lock);
                m->queue_io = 1;
@@ -185,6 +180,8 @@ static struct multipath *alloc_multipath(void)
                        kfree(m);
                        return NULL;
                }
+               m->ti = ti;
+               ti->private = m;
        }
 
        return m;
@@ -557,8 +554,7 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps,
 }
 
 static struct priority_group *parse_priority_group(struct arg_set *as,
-                                                  struct multipath *m,
-                                                  struct dm_target *ti)
+                                                  struct multipath *m)
 {
        static struct param _params[] = {
                {1, 1024, "invalid number of paths"},
@@ -568,6 +564,7 @@ static struct priority_group *parse_priority_group(struct arg_set *as,
        int r;
        unsigned i, nr_selector_args, nr_params;
        struct priority_group *pg;
+       struct dm_target *ti = m->ti;
 
        if (as->argc < 2) {
                as->argc = 0;
@@ -624,12 +621,12 @@ static struct priority_group *parse_priority_group(struct arg_set *as,
        return NULL;
 }
 
-static int parse_hw_handler(struct arg_set *as, struct multipath *m,
-                           struct dm_target *ti)
+static int parse_hw_handler(struct arg_set *as, struct multipath *m)
 {
        int r;
        struct hw_handler_type *hwht;
        unsigned hw_argc;
+       struct dm_target *ti = m->ti;
 
        static struct param _params[] = {
                {0, 1024, "invalid number of hardware handler args"},
@@ -661,11 +658,11 @@ static int parse_hw_handler(struct arg_set *as, struct multipath *m,
        return 0;
 }
 
-static int parse_features(struct arg_set *as, struct multipath *m,
-                         struct dm_target *ti)
+static int parse_features(struct arg_set *as, struct multipath *m)
 {
        int r;
        unsigned argc;
+       struct dm_target *ti = m->ti;
 
        static struct param _params[] = {
                {0, 1, "invalid number of feature args"},
@@ -704,19 +701,17 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc,
        as.argc = argc;
        as.argv = argv;
 
-       m = alloc_multipath();
+       m = alloc_multipath(ti);
        if (!m) {
                ti->error = "can't allocate multipath";
                return -EINVAL;
        }
 
-       m->ti = ti;
-
-       r = parse_features(&as, m, ti);
+       r = parse_features(&as, m);
        if (r)
                goto bad;
 
-       r = parse_hw_handler(&as, m, ti);
+       r = parse_hw_handler(&as, m);
        if (r)
                goto bad;
 
@@ -732,7 +727,7 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc,
        while (as.argc) {
                struct priority_group *pg;
 
-               pg = parse_priority_group(&as, m, ti);
+               pg = parse_priority_group(&as, m);
                if (!pg) {
                        r = -EINVAL;
                        goto bad;
@@ -752,8 +747,6 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc,
                goto bad;
        }
 
-       ti->private = m;
-
        return 0;
 
  bad:
@@ -1266,12 +1259,47 @@ error:
        return -EINVAL;
 }
 
+static int multipath_ioctl(struct dm_target *ti, struct inode *inode,
+                          struct file *filp, unsigned int cmd,
+                          unsigned long arg)
+{
+       struct multipath *m = (struct multipath *) ti->private;
+       struct block_device *bdev = NULL;
+       unsigned long flags;
+       struct file fake_file = {};
+       struct dentry fake_dentry = {};
+       int r = 0;
+
+       fake_file.f_dentry = &fake_dentry;
+
+       spin_lock_irqsave(&m->lock, flags);
+
+       if (!m->current_pgpath)
+               __choose_pgpath(m);
+
+       if (m->current_pgpath) {
+               bdev = m->current_pgpath->path.dev->bdev;
+               fake_dentry.d_inode = bdev->bd_inode;
+               fake_file.f_mode = m->current_pgpath->path.dev->mode;
+       }
+
+       if (m->queue_io)
+               r = -EAGAIN;
+       else if (!bdev)
+               r = -EIO;
+
+       spin_unlock_irqrestore(&m->lock, flags);
+
+       return r ? : blkdev_driver_ioctl(bdev->bd_inode, &fake_file,
+                                        bdev->bd_disk, cmd, arg);
+}
+
 /*-----------------------------------------------------------------
  * Module setup
  *---------------------------------------------------------------*/
 static struct target_type multipath_target = {
        .name = "multipath",
-       .version = {1, 0, 4},
+       .version = {1, 0, 5},
        .module = THIS_MODULE,
        .ctr = multipath_ctr,
        .dtr = multipath_dtr,
@@ -1281,6 +1309,7 @@ static struct target_type multipath_target = {
        .resume = multipath_resume,
        .status = multipath_status,
        .message = multipath_message,
+       .ioctl  = multipath_ioctl,
 };
 
 static int __init dm_multipath_init(void)
index c54de989eb005e74738800557f37f1ce0459753f..659224cb7c533d6a7dba75e84cf03ab2ced13a0c 100644 (file)
@@ -1213,9 +1213,9 @@ static int mirror_status(struct dm_target *ti, status_type_t type,
                break;
 
        case STATUSTYPE_TABLE:
-               DMEMIT("%d ", ms->nr_mirrors);
+               DMEMIT("%d", ms->nr_mirrors);
                for (m = 0; m < ms->nr_mirrors; m++)
-                       DMEMIT("%s %llu ", ms->mirror[m].dev->name,
+                       DMEMIT(" %s %llu", ms->mirror[m].dev->name,
                                (unsigned long long)ms->mirror[m].offset);
        }
 
index 1d0fafda0f761abb3630bd180f628dd7dfbbbc4d..5281e0094072b28fd5714ca8227d54c616422352 100644 (file)
@@ -39,6 +39,9 @@
  */
 #define SNAPSHOT_PAGES 256
 
+struct workqueue_struct *ksnapd;
+static void flush_queued_bios(void *data);
+
 struct pending_exception {
        struct exception e;
 
@@ -56,7 +59,7 @@ struct pending_exception {
 
        /*
         * The primary pending_exception is the one that holds
-        * the sibling_count and the list of origin_bios for a
+        * the ref_count and the list of origin_bios for a
         * group of pending_exceptions.  It is always last to get freed.
         * These fields get set up when writing to the origin.
         */
@@ -69,7 +72,7 @@ struct pending_exception {
         * the sibling concerned and not pe->primary_pe->snap->lock unless
         * they are the same.
         */
-       atomic_t sibling_count;
+       atomic_t ref_count;
 
        /* Pointer back to snapshot context */
        struct dm_snapshot *snap;
@@ -387,15 +390,46 @@ static inline ulong round_up(ulong n, ulong size)
        return (n + size) & ~size;
 }
 
-static void read_snapshot_metadata(struct dm_snapshot *s)
+static int set_chunk_size(struct dm_snapshot *s, const char *chunk_size_arg,
+                         char **error)
 {
-       if (s->store.read_metadata(&s->store)) {
-               down_write(&s->lock);
-               s->valid = 0;
-               up_write(&s->lock);
+       unsigned long chunk_size;
+       char *value;
+
+       chunk_size = simple_strtoul(chunk_size_arg, &value, 10);
+       if (*chunk_size_arg == '\0' || *value != '\0') {
+               *error = "Invalid chunk size";
+               return -EINVAL;
+       }
+
+       if (!chunk_size) {
+               s->chunk_size = s->chunk_mask = s->chunk_shift = 0;
+               return 0;
+       }
+
+       /*
+        * Chunk size must be multiple of page size.  Silently
+        * round up if it's not.
+        */
+       chunk_size = round_up(chunk_size, PAGE_SIZE >> 9);
+
+       /* Check chunk_size is a power of 2 */
+       if (chunk_size & (chunk_size - 1)) {
+               *error = "Chunk size is not a power of 2";
+               return -EINVAL;
+       }
 
-               dm_table_event(s->table);
+       /* Validate the chunk size against the device block size */
+       if (chunk_size % (bdev_hardsect_size(s->cow->bdev) >> 9)) {
+               *error = "Chunk size is not a multiple of device blocksize";
+               return -EINVAL;
        }
+
+       s->chunk_size = chunk_size;
+       s->chunk_mask = chunk_size - 1;
+       s->chunk_shift = ffs(chunk_size) - 1;
+
+       return 0;
 }
 
 /*
@@ -404,15 +438,12 @@ static void read_snapshot_metadata(struct dm_snapshot *s)
 static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 {
        struct dm_snapshot *s;
-       unsigned long chunk_size;
        int r = -EINVAL;
        char persistent;
        char *origin_path;
        char *cow_path;
-       char *value;
-       int blocksize;
 
-       if (argc < 4) {
+       if (argc != 4) {
                ti->error = "requires exactly 4 arguments";
                r = -EINVAL;
                goto bad1;
@@ -428,13 +459,6 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
                goto bad1;
        }
 
-       chunk_size = simple_strtoul(argv[3], &value, 10);
-       if (chunk_size == 0 || value == NULL) {
-               ti->error = "Invalid chunk size";
-               r = -EINVAL;
-               goto bad1;
-       }
-
        s = kmalloc(sizeof(*s), GFP_KERNEL);
        if (s == NULL) {
                ti->error = "Cannot allocate snapshot context private "
@@ -457,36 +481,17 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
                goto bad2;
        }
 
-       /*
-        * Chunk size must be multiple of page size.  Silently
-        * round up if it's not.
-        */
-       chunk_size = round_up(chunk_size, PAGE_SIZE >> 9);
-
-       /* Validate the chunk size against the device block size */
-       blocksize = s->cow->bdev->bd_disk->queue->hardsect_size;
-       if (chunk_size % (blocksize >> 9)) {
-               ti->error = "Chunk size is not a multiple of device blocksize";
-               r = -EINVAL;
-               goto bad3;
-       }
-
-       /* Check chunk_size is a power of 2 */
-       if (chunk_size & (chunk_size - 1)) {
-               ti->error = "Chunk size is not a power of 2";
-               r = -EINVAL;
+       r = set_chunk_size(s, argv[3], &ti->error);
+       if (r)
                goto bad3;
-       }
 
-       s->chunk_size = chunk_size;
-       s->chunk_mask = chunk_size - 1;
        s->type = persistent;
-       s->chunk_shift = ffs(chunk_size) - 1;
 
        s->valid = 1;
        s->active = 0;
        s->last_percent = 0;
        init_rwsem(&s->lock);
+       spin_lock_init(&s->pe_lock);
        s->table = ti->table;
 
        /* Allocate hash table for COW data */
@@ -496,16 +501,12 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
                goto bad3;
        }
 
-       /*
-        * Check the persistent flag - done here because we need the iobuf
-        * to check the LV header
-        */
        s->store.snap = s;
 
        if (persistent == 'P')
-               r = dm_create_persistent(&s->store, chunk_size);
+               r = dm_create_persistent(&s->store);
        else
-               r = dm_create_transient(&s->store, s, blocksize);
+               r = dm_create_transient(&s->store);
 
        if (r) {
                ti->error = "Couldn't create exception store";
@@ -520,7 +521,14 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        }
 
        /* Metadata must only be loaded into one table at once */
-       read_snapshot_metadata(s);
+       r = s->store.read_metadata(&s->store);
+       if (r) {
+               ti->error = "Failed to read snapshot metadata";
+               goto bad6;
+       }
+
+       bio_list_init(&s->queued_bios);
+       INIT_WORK(&s->queued_bios_work, flush_queued_bios, s);
 
        /* Add snapshot to the list of snapshots for this origin */
        /* Exceptions aren't triggered till snapshot_resume() is called */
@@ -560,6 +568,8 @@ static void snapshot_dtr(struct dm_target *ti)
 {
        struct dm_snapshot *s = (struct dm_snapshot *) ti->private;
 
+       flush_workqueue(ksnapd);
+
        /* Prevent further origin writes from using this snapshot. */
        /* After this returns there can be no new kcopyd jobs. */
        unregister_snapshot(s);
@@ -593,6 +603,19 @@ static void flush_bios(struct bio *bio)
        }
 }
 
+static void flush_queued_bios(void *data)
+{
+       struct dm_snapshot *s = (struct dm_snapshot *) data;
+       struct bio *queued_bios;
+       unsigned long flags;
+
+       spin_lock_irqsave(&s->pe_lock, flags);
+       queued_bios = bio_list_get(&s->queued_bios);
+       spin_unlock_irqrestore(&s->pe_lock, flags);
+
+       flush_bios(queued_bios);
+}
+
 /*
  * Error a list of buffers.
  */
@@ -608,28 +631,7 @@ static void error_bios(struct bio *bio)
        }
 }
 
-static inline void error_snapshot_bios(struct pending_exception *pe)
-{
-       error_bios(bio_list_get(&pe->snapshot_bios));
-}
-
-static struct bio *__flush_bios(struct pending_exception *pe)
-{
-       /*
-        * If this pe is involved in a write to the origin and
-        * it is the last sibling to complete then release
-        * the bios for the original write to the origin.
-        */
-
-       if (pe->primary_pe &&
-           atomic_dec_and_test(&pe->primary_pe->sibling_count))
-               return bio_list_get(&pe->primary_pe->origin_bios);
-
-       return NULL;
-}
-
-static void __invalidate_snapshot(struct dm_snapshot *s,
-                               struct pending_exception *pe, int err)
+static void __invalidate_snapshot(struct dm_snapshot *s, int err)
 {
        if (!s->valid)
                return;
@@ -639,9 +641,6 @@ static void __invalidate_snapshot(struct dm_snapshot *s,
        else if (err == -ENOMEM)
                DMERR("Invalidating snapshot: Unable to allocate exception.");
 
-       if (pe)
-               remove_exception(&pe->e);
-
        if (s->store.drop_snapshot)
                s->store.drop_snapshot(&s->store);
 
@@ -650,78 +649,95 @@ static void __invalidate_snapshot(struct dm_snapshot *s,
        dm_table_event(s->table);
 }
 
+static void get_pending_exception(struct pending_exception *pe)
+{
+       atomic_inc(&pe->ref_count);
+}
+
+static struct bio *put_pending_exception(struct pending_exception *pe)
+{
+       struct pending_exception *primary_pe;
+       struct bio *origin_bios = NULL;
+
+       primary_pe = pe->primary_pe;
+
+       /*
+        * If this pe is involved in a write to the origin and
+        * it is the last sibling to complete then release
+        * the bios for the original write to the origin.
+        */
+       if (primary_pe &&
+           atomic_dec_and_test(&primary_pe->ref_count))
+               origin_bios = bio_list_get(&primary_pe->origin_bios);
+
+       /*
+        * Free the pe if it's not linked to an origin write or if
+        * it's not itself a primary pe.
+        */
+       if (!primary_pe || primary_pe != pe)
+               free_pending_exception(pe);
+
+       /*
+        * Free the primary pe if nothing references it.
+        */
+       if (primary_pe && !atomic_read(&primary_pe->ref_count))
+               free_pending_exception(primary_pe);
+
+       return origin_bios;
+}
+
 static void pending_complete(struct pending_exception *pe, int success)
 {
        struct exception *e;
-       struct pending_exception *primary_pe;
        struct dm_snapshot *s = pe->snap;
-       struct bio *flush = NULL;
+       struct bio *origin_bios = NULL;
+       struct bio *snapshot_bios = NULL;
+       int error = 0;
 
        if (!success) {
                /* Read/write error - snapshot is unusable */
                down_write(&s->lock);
-               __invalidate_snapshot(s, pe, -EIO);
-               flush = __flush_bios(pe);
-               up_write(&s->lock);
-
-               error_snapshot_bios(pe);
+               __invalidate_snapshot(s, -EIO);
+               error = 1;
                goto out;
        }
 
        e = alloc_exception();
        if (!e) {
                down_write(&s->lock);
-               __invalidate_snapshot(s, pe, -ENOMEM);
-               flush = __flush_bios(pe);
-               up_write(&s->lock);
-
-               error_snapshot_bios(pe);
+               __invalidate_snapshot(s, -ENOMEM);
+               error = 1;
                goto out;
        }
        *e = pe->e;
 
-       /*
-        * Add a proper exception, and remove the
-        * in-flight exception from the list.
-        */
        down_write(&s->lock);
        if (!s->valid) {
-               flush = __flush_bios(pe);
-               up_write(&s->lock);
-
                free_exception(e);
-
-               error_snapshot_bios(pe);
+               error = 1;
                goto out;
        }
 
+       /*
+        * Add a proper exception, and remove the
+        * in-flight exception from the list.
+        */
        insert_exception(&s->complete, e);
+
+ out:
        remove_exception(&pe->e);
-       flush = __flush_bios(pe);
+       snapshot_bios = bio_list_get(&pe->snapshot_bios);
+       origin_bios = put_pending_exception(pe);
 
        up_write(&s->lock);
 
        /* Submit any pending write bios */
-       flush_bios(bio_list_get(&pe->snapshot_bios));
-
- out:
-       primary_pe = pe->primary_pe;
-
-       /*
-        * Free the pe if it's not linked to an origin write or if
-        * it's not itself a primary pe.
-        */
-       if (!primary_pe || primary_pe != pe)
-               free_pending_exception(pe);
-
-       /*
-        * Free the primary pe if nothing references it.
-        */
-       if (primary_pe && !atomic_read(&primary_pe->sibling_count))
-               free_pending_exception(primary_pe);
+       if (error)
+               error_bios(snapshot_bios);
+       else
+               flush_bios(snapshot_bios);
 
-       if (flush)
-               flush_bios(flush);
+       flush_bios(origin_bios);
 }
 
 static void commit_callback(void *context, int success)
@@ -822,7 +838,7 @@ __find_pending_exception(struct dm_snapshot *s, struct bio *bio)
        bio_list_init(&pe->origin_bios);
        bio_list_init(&pe->snapshot_bios);
        pe->primary_pe = NULL;
-       atomic_set(&pe->sibling_count, 1);
+       atomic_set(&pe->ref_count, 0);
        pe->snap = s;
        pe->started = 0;
 
@@ -831,6 +847,7 @@ __find_pending_exception(struct dm_snapshot *s, struct bio *bio)
                return NULL;
        }
 
+       get_pending_exception(pe);
        insert_exception(&s->pending, &pe->e);
 
  out:
@@ -850,7 +867,6 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
 {
        struct exception *e;
        struct dm_snapshot *s = (struct dm_snapshot *) ti->private;
-       int copy_needed = 0;
        int r = 1;
        chunk_t chunk;
        struct pending_exception *pe = NULL;
@@ -865,32 +881,31 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
        if (unlikely(bio_barrier(bio)))
                return -EOPNOTSUPP;
 
+       /* FIXME: should only take write lock if we need
+        * to copy an exception */
+       down_write(&s->lock);
+
+       if (!s->valid) {
+               r = -EIO;
+               goto out_unlock;
+       }
+
+       /* If the block is already remapped - use that, else remap it */
+       e = lookup_exception(&s->complete, chunk);
+       if (e) {
+               remap_exception(s, e, bio);
+               goto out_unlock;
+       }
+
        /*
         * Write to snapshot - higher level takes care of RW/RO
         * flags so we should only get this if we are
         * writeable.
         */
        if (bio_rw(bio) == WRITE) {
-
-               /* FIXME: should only take write lock if we need
-                * to copy an exception */
-               down_write(&s->lock);
-
-               if (!s->valid) {
-                       r = -EIO;
-                       goto out_unlock;
-               }
-
-               /* If the block is already remapped - use that, else remap it */
-               e = lookup_exception(&s->complete, chunk);
-               if (e) {
-                       remap_exception(s, e, bio);
-                       goto out_unlock;
-               }
-
                pe = __find_pending_exception(s, bio);
                if (!pe) {
-                       __invalidate_snapshot(s, pe, -ENOMEM);
+                       __invalidate_snapshot(s, -ENOMEM);
                        r = -EIO;
                        goto out_unlock;
                }
@@ -898,45 +913,27 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
                remap_exception(s, &pe->e, bio);
                bio_list_add(&pe->snapshot_bios, bio);
 
+               r = 0;
+
                if (!pe->started) {
                        /* this is protected by snap->lock */
                        pe->started = 1;
-                       copy_needed = 1;
-               }
-
-               r = 0;
-
- out_unlock:
-               up_write(&s->lock);
-
-               if (copy_needed)
+                       up_write(&s->lock);
                        start_copy(pe);
-       } else {
+                       goto out;
+               }
+       } else
                /*
                 * FIXME: this read path scares me because we
                 * always use the origin when we have a pending
                 * exception.  However I can't think of a
                 * situation where this is wrong - ejt.
                 */
+               bio->bi_bdev = s->origin->bdev;
 
-               /* Do reads */
-               down_read(&s->lock);
-
-               if (!s->valid) {
-                       up_read(&s->lock);
-                       return -EIO;
-               }
-
-               /* See if it it has been remapped */
-               e = lookup_exception(&s->complete, chunk);
-               if (e)
-                       remap_exception(s, e, bio);
-               else
-                       bio->bi_bdev = s->origin->bdev;
-
-               up_read(&s->lock);
-       }
-
+ out_unlock:
+       up_write(&s->lock);
+ out:
        return r;
 }
 
@@ -1025,7 +1022,7 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
                 * is already remapped in this snapshot
                 * and trigger an exception if not.
                 *
-                * sibling_count is initialised to 1 so pending_complete()
+                * ref_count is initialised to 1 so pending_complete()
                 * won't destroy the primary_pe while we're inside this loop.
                 */
                e = lookup_exception(&snap->complete, chunk);
@@ -1034,7 +1031,7 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
 
                pe = __find_pending_exception(snap, bio);
                if (!pe) {
-                       __invalidate_snapshot(snap, pe, ENOMEM);
+                       __invalidate_snapshot(snap, -ENOMEM);
                        goto next_snapshot;
                }
 
@@ -1056,8 +1053,8 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
                }
 
                if (!pe->primary_pe) {
-                       atomic_inc(&primary_pe->sibling_count);
                        pe->primary_pe = primary_pe;
+                       get_pending_exception(primary_pe);
                }
 
                if (!pe->started) {
@@ -1070,20 +1067,20 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
        }
 
        if (!primary_pe)
-               goto out;
+               return r;
 
        /*
         * If this is the first time we're processing this chunk and
-        * sibling_count is now 1 it means all the pending exceptions
+        * ref_count is now 1 it means all the pending exceptions
         * got completed while we were in the loop above, so it falls to
         * us here to remove the primary_pe and submit any origin_bios.
         */
 
-       if (first && atomic_dec_and_test(&primary_pe->sibling_count)) {
+       if (first && atomic_dec_and_test(&primary_pe->ref_count)) {
                flush_bios(bio_list_get(&primary_pe->origin_bios));
                free_pending_exception(primary_pe);
                /* If we got here, pe_queue is necessarily empty. */
-               goto out;
+               return r;
        }
 
        /*
@@ -1092,7 +1089,6 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
        list_for_each_entry_safe(pe, next_pe, &pe_queue, list)
                start_copy(pe);
 
- out:
        return r;
 }
 
@@ -1205,7 +1201,7 @@ static int origin_status(struct dm_target *ti, status_type_t type, char *result,
 
 static struct target_type origin_target = {
        .name    = "snapshot-origin",
-       .version = {1, 4, 0},
+       .version = {1, 5, 0},
        .module  = THIS_MODULE,
        .ctr     = origin_ctr,
        .dtr     = origin_dtr,
@@ -1216,7 +1212,7 @@ static struct target_type origin_target = {
 
 static struct target_type snapshot_target = {
        .name    = "snapshot",
-       .version = {1, 4, 0},
+       .version = {1, 5, 0},
        .module  = THIS_MODULE,
        .ctr     = snapshot_ctr,
        .dtr     = snapshot_dtr,
@@ -1275,8 +1271,17 @@ static int __init dm_snapshot_init(void)
                goto bad5;
        }
 
+       ksnapd = create_singlethread_workqueue("ksnapd");
+       if (!ksnapd) {
+               DMERR("Failed to create ksnapd workqueue.");
+               r = -ENOMEM;
+               goto bad6;
+       }
+
        return 0;
 
+      bad6:
+       mempool_destroy(pending_pool);
       bad5:
        kmem_cache_destroy(pending_cache);
       bad4:
@@ -1294,6 +1299,8 @@ static void __exit dm_snapshot_exit(void)
 {
        int r;
 
+       destroy_workqueue(ksnapd);
+
        r = dm_unregister_target(&snapshot_target);
        if (r)
                DMERR("snapshot unregister failed %d", r);
index fdec1e2dc87183926cac41e1d62fc961e9aab851..15fa2ae6cdc2971f590a814578d06536b75b8484 100644 (file)
@@ -10,7 +10,9 @@
 #define DM_SNAPSHOT_H
 
 #include "dm.h"
+#include "dm-bio-list.h"
 #include <linux/blkdev.h>
+#include <linux/workqueue.h>
 
 struct exception_table {
        uint32_t hash_mask;
@@ -112,10 +114,20 @@ struct dm_snapshot {
        struct exception_table pending;
        struct exception_table complete;
 
+       /*
+        * pe_lock protects all pending_exception operations and access
+        * as well as the snapshot_bios list.
+        */
+       spinlock_t pe_lock;
+
        /* The on disk metadata handler */
        struct exception_store store;
 
        struct kcopyd_client *kcopyd_client;
+
+       /* Queue of snapshot writes for ksnapd to flush */
+       struct bio_list queued_bios;
+       struct work_struct queued_bios_work;
 };
 
 /*
@@ -128,10 +140,9 @@ int dm_add_exception(struct dm_snapshot *s, chunk_t old, chunk_t new);
  * Constructor and destructor for the default persistent
  * store.
  */
-int dm_create_persistent(struct exception_store *store, uint32_t chunk_size);
+int dm_create_persistent(struct exception_store *store);
 
-int dm_create_transient(struct exception_store *store,
-                       struct dm_snapshot *s, int blocksize);
+int dm_create_transient(struct exception_store *store);
 
 /*
  * Return the number of sectors in the device.
index 75fe9493e6af47059dbe79819b16683455304be8..05befa91807a332b87676bef2cc47de92417e1eb 100644 (file)
@@ -522,56 +522,61 @@ static int __table_get_device(struct dm_table *t, struct dm_target *ti,
        return 0;
 }
 
-
-int dm_get_device(struct dm_target *ti, const char *path, sector_t start,
-                 sector_t len, int mode, struct dm_dev **result)
+void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev)
 {
-       int r = __table_get_device(ti->table, ti, path,
-                                  start, len, mode, result);
-       if (!r) {
-               request_queue_t *q = bdev_get_queue((*result)->bdev);
-               struct io_restrictions *rs = &ti->limits;
-
-               /*
-                * Combine the device limits low.
-                *
-                * FIXME: if we move an io_restriction struct
-                *        into q this would just be a call to
-                *        combine_restrictions_low()
-                */
+       request_queue_t *q = bdev_get_queue(bdev);
+       struct io_restrictions *rs = &ti->limits;
+
+       /*
+        * Combine the device limits low.
+        *
+        * FIXME: if we move an io_restriction struct
+        *        into q this would just be a call to
+        *        combine_restrictions_low()
+        */
+       rs->max_sectors =
+               min_not_zero(rs->max_sectors, q->max_sectors);
+
+       /* FIXME: Device-Mapper on top of RAID-0 breaks because DM
+        *        currently doesn't honor MD's merge_bvec_fn routine.
+        *        In this case, we'll force DM to use PAGE_SIZE or
+        *        smaller I/O, just to be safe. A better fix is in the
+        *        works, but add this for the time being so it will at
+        *        least operate correctly.
+        */
+       if (q->merge_bvec_fn)
                rs->max_sectors =
-                       min_not_zero(rs->max_sectors, q->max_sectors);
+                       min_not_zero(rs->max_sectors,
+                                    (unsigned int) (PAGE_SIZE >> 9));
 
-               /* FIXME: Device-Mapper on top of RAID-0 breaks because DM
-                *        currently doesn't honor MD's merge_bvec_fn routine.
-                *        In this case, we'll force DM to use PAGE_SIZE or
-                *        smaller I/O, just to be safe. A better fix is in the
-                *        works, but add this for the time being so it will at
-                *        least operate correctly.
-                */
-               if (q->merge_bvec_fn)
-                       rs->max_sectors =
-                               min_not_zero(rs->max_sectors,
-                                            (unsigned int) (PAGE_SIZE >> 9));
+       rs->max_phys_segments =
+               min_not_zero(rs->max_phys_segments,
+                            q->max_phys_segments);
 
-               rs->max_phys_segments =
-                       min_not_zero(rs->max_phys_segments,
-                                    q->max_phys_segments);
+       rs->max_hw_segments =
+               min_not_zero(rs->max_hw_segments, q->max_hw_segments);
 
-               rs->max_hw_segments =
-                       min_not_zero(rs->max_hw_segments, q->max_hw_segments);
+       rs->hardsect_size = max(rs->hardsect_size, q->hardsect_size);
 
-               rs->hardsect_size = max(rs->hardsect_size, q->hardsect_size);
+       rs->max_segment_size =
+               min_not_zero(rs->max_segment_size, q->max_segment_size);
 
-               rs->max_segment_size =
-                       min_not_zero(rs->max_segment_size, q->max_segment_size);
+       rs->seg_boundary_mask =
+               min_not_zero(rs->seg_boundary_mask,
+                            q->seg_boundary_mask);
 
-               rs->seg_boundary_mask =
-                       min_not_zero(rs->seg_boundary_mask,
-                                    q->seg_boundary_mask);
+       rs->no_cluster |= !test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
+}
+EXPORT_SYMBOL_GPL(dm_set_device_limits);
 
-               rs->no_cluster |= !test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
-       }
+int dm_get_device(struct dm_target *ti, const char *path, sector_t start,
+                 sector_t len, int mode, struct dm_dev **result)
+{
+       int r = __table_get_device(ti->table, ti, path,
+                                  start, len, mode, result);
+
+       if (!r)
+               dm_set_device_limits(ti, (*result)->bdev);
 
        return r;
 }
@@ -939,9 +944,20 @@ void dm_table_postsuspend_targets(struct dm_table *t)
        return suspend_targets(t, 1);
 }
 
-void dm_table_resume_targets(struct dm_table *t)
+int dm_table_resume_targets(struct dm_table *t)
 {
-       int i;
+       int i, r = 0;
+
+       for (i = 0; i < t->num_targets; i++) {
+               struct dm_target *ti = t->targets + i;
+
+               if (!ti->type->preresume)
+                       continue;
+
+               r = ti->type->preresume(ti);
+               if (r)
+                       return r;
+       }
 
        for (i = 0; i < t->num_targets; i++) {
                struct dm_target *ti = t->targets + i;
@@ -949,6 +965,8 @@ void dm_table_resume_targets(struct dm_table *t)
                if (ti->type->resume)
                        ti->type->resume(ti);
        }
+
+       return 0;
 }
 
 int dm_table_any_congested(struct dm_table *t, int bdi_bits)
@@ -983,6 +1001,11 @@ int dm_table_flush_all(struct dm_table *t)
 {
        struct list_head *d, *devices = dm_table_get_devices(t);
        int ret = 0;
+       unsigned i;
+
+       for (i = 0; i < t->num_targets; i++)
+               if (t->targets[i].type->flush)
+                       t->targets[i].type->flush(&t->targets[i]);
 
        for (d = devices->next; d != devices; d = d->next) {
                struct dm_dev *dd = list_entry(d, struct dm_dev, list);
index c99bf9f017599a1002a15f608ea356639239dedd..b5764a86c8b56f3f44b8ca2ebc38d30af8389a44 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/idr.h>
 #include <linux/hdreg.h>
 #include <linux/blktrace_api.h>
+#include <linux/smp_lock.h>
 
 #define DM_MSG_PREFIX "core"
 
@@ -101,6 +102,8 @@ struct mapped_device {
        mempool_t *io_pool;
        mempool_t *tio_pool;
 
+       struct bio_set *bs;
+
        /*
         * Event handling.
         */
@@ -121,16 +124,10 @@ struct mapped_device {
 static kmem_cache_t *_io_cache;
 static kmem_cache_t *_tio_cache;
 
-static struct bio_set *dm_set;
-
 static int __init local_init(void)
 {
        int r;
 
-       dm_set = bioset_create(16, 16, 4);
-       if (!dm_set)
-               return -ENOMEM;
-
        /* allocate a slab for the dm_ios */
        _io_cache = kmem_cache_create("dm_io",
                                      sizeof(struct dm_io), 0, 0, NULL, NULL);
@@ -164,8 +161,6 @@ static void local_exit(void)
        kmem_cache_destroy(_tio_cache);
        kmem_cache_destroy(_io_cache);
 
-       bioset_free(dm_set);
-
        if (unregister_blkdev(_major, _name) < 0)
                DMERR("unregister_blkdev failed");
 
@@ -288,6 +283,45 @@ static int dm_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
        return dm_get_geometry(md, geo);
 }
 
+static int dm_blk_ioctl(struct inode *inode, struct file *file,
+                       unsigned int cmd, unsigned long arg)
+{
+       struct mapped_device *md;
+       struct dm_table *map;
+       struct dm_target *tgt;
+       int r = -ENOTTY;
+
+       /* We don't really need this lock, but we do need 'inode'. */
+       unlock_kernel();
+
+       md = inode->i_bdev->bd_disk->private_data;
+
+       map = dm_get_table(md);
+
+       if (!map || !dm_table_get_size(map))
+               goto out;
+
+       /* We only support devices that have a single target */
+       if (dm_table_get_num_targets(map) != 1)
+               goto out;
+
+       tgt = dm_table_get_target(map, 0);
+
+       if (dm_suspended(md)) {
+               r = -EAGAIN;
+               goto out;
+       }
+
+       if (tgt->type->ioctl)
+               r = tgt->type->ioctl(tgt, inode, file, cmd, arg);
+
+out:
+       dm_table_put(map);
+
+       lock_kernel();
+       return r;
+}
+
 static inline struct dm_io *alloc_io(struct mapped_device *md)
 {
        return mempool_alloc(md->io_pool, GFP_NOIO);
@@ -435,7 +469,7 @@ static int clone_endio(struct bio *bio, unsigned int done, int error)
 {
        int r = 0;
        struct target_io *tio = bio->bi_private;
-       struct dm_io *io = tio->io;
+       struct mapped_device *md = tio->io->md;
        dm_endio_fn endio = tio->ti->type->end_io;
 
        if (bio->bi_size)
@@ -454,9 +488,15 @@ static int clone_endio(struct bio *bio, unsigned int done, int error)
                        return 1;
        }
 
-       free_tio(io->md, tio);
-       dec_pending(io, error);
+       dec_pending(tio->io, error);
+
+       /*
+        * Store md for cleanup instead of tio which is about to get freed.
+        */
+       bio->bi_private = md->bs;
+
        bio_put(bio);
+       free_tio(md, tio);
        return r;
 }
 
@@ -485,6 +525,7 @@ static void __map_bio(struct dm_target *ti, struct bio *clone,
 {
        int r;
        sector_t sector;
+       struct mapped_device *md;
 
        /*
         * Sanity checks.
@@ -514,10 +555,14 @@ static void __map_bio(struct dm_target *ti, struct bio *clone,
 
        else if (r < 0) {
                /* error the io and bail out */
-               struct dm_io *io = tio->io;
-               free_tio(tio->io->md, tio);
-               dec_pending(io, r);
+               md = tio->io->md;
+               dec_pending(tio->io, r);
+               /*
+                * Store bio_set for cleanup.
+                */
+               clone->bi_private = md->bs;
                bio_put(clone);
+               free_tio(md, tio);
        }
 }
 
@@ -533,7 +578,9 @@ struct clone_info {
 
 static void dm_bio_destructor(struct bio *bio)
 {
-       bio_free(bio, dm_set);
+       struct bio_set *bs = bio->bi_private;
+
+       bio_free(bio, bs);
 }
 
 /*
@@ -541,12 +588,12 @@ static void dm_bio_destructor(struct bio *bio)
  */
 static struct bio *split_bvec(struct bio *bio, sector_t sector,
                              unsigned short idx, unsigned int offset,
-                             unsigned int len)
+                             unsigned int len, struct bio_set *bs)
 {
        struct bio *clone;
        struct bio_vec *bv = bio->bi_io_vec + idx;
 
-       clone = bio_alloc_bioset(GFP_NOIO, 1, dm_set);
+       clone = bio_alloc_bioset(GFP_NOIO, 1, bs);
        clone->bi_destructor = dm_bio_destructor;
        *clone->bi_io_vec = *bv;
 
@@ -566,11 +613,13 @@ static struct bio *split_bvec(struct bio *bio, sector_t sector,
  */
 static struct bio *clone_bio(struct bio *bio, sector_t sector,
                             unsigned short idx, unsigned short bv_count,
-                            unsigned int len)
+                            unsigned int len, struct bio_set *bs)
 {
        struct bio *clone;
 
-       clone = bio_clone(bio, GFP_NOIO);
+       clone = bio_alloc_bioset(GFP_NOIO, bio->bi_max_vecs, bs);
+       __bio_clone(clone, bio);
+       clone->bi_destructor = dm_bio_destructor;
        clone->bi_sector = sector;
        clone->bi_idx = idx;
        clone->bi_vcnt = idx + bv_count;
@@ -601,7 +650,8 @@ static void __clone_and_map(struct clone_info *ci)
                 * the remaining io with a single clone.
                 */
                clone = clone_bio(bio, ci->sector, ci->idx,
-                                 bio->bi_vcnt - ci->idx, ci->sector_count);
+                                 bio->bi_vcnt - ci->idx, ci->sector_count,
+                                 ci->md->bs);
                __map_bio(ti, clone, tio);
                ci->sector_count = 0;
 
@@ -624,7 +674,8 @@ static void __clone_and_map(struct clone_info *ci)
                        len += bv_len;
                }
 
-               clone = clone_bio(bio, ci->sector, ci->idx, i - ci->idx, len);
+               clone = clone_bio(bio, ci->sector, ci->idx, i - ci->idx, len,
+                                 ci->md->bs);
                __map_bio(ti, clone, tio);
 
                ci->sector += len;
@@ -653,7 +704,8 @@ static void __clone_and_map(struct clone_info *ci)
                        len = min(remaining, max);
 
                        clone = split_bvec(bio, ci->sector, ci->idx,
-                                          bv->bv_offset + offset, len);
+                                          bv->bv_offset + offset, len,
+                                          ci->md->bs);
 
                        __map_bio(ti, clone, tio);
 
@@ -903,7 +955,7 @@ static struct mapped_device *alloc_dev(int minor)
 
        md->queue = blk_alloc_queue(GFP_KERNEL);
        if (!md->queue)
-               goto bad1;
+               goto bad1_free_minor;
 
        md->queue->queuedata = md;
        md->queue->backing_dev_info.congested_fn = dm_any_congested;
@@ -921,6 +973,10 @@ static struct mapped_device *alloc_dev(int minor)
        if (!md->tio_pool)
                goto bad3;
 
+       md->bs = bioset_create(16, 16, 4);
+       if (!md->bs)
+               goto bad_no_bioset;
+
        md->disk = alloc_disk(1);
        if (!md->disk)
                goto bad4;
@@ -948,11 +1004,14 @@ static struct mapped_device *alloc_dev(int minor)
        return md;
 
  bad4:
+       bioset_free(md->bs);
+ bad_no_bioset:
        mempool_destroy(md->tio_pool);
  bad3:
        mempool_destroy(md->io_pool);
  bad2:
        blk_cleanup_queue(md->queue);
+ bad1_free_minor:
        free_minor(minor);
  bad1:
        module_put(THIS_MODULE);
@@ -971,6 +1030,7 @@ static void free_dev(struct mapped_device *md)
        }
        mempool_destroy(md->tio_pool);
        mempool_destroy(md->io_pool);
+       bioset_free(md->bs);
        del_gendisk(md->disk);
        free_minor(minor);
 
@@ -1319,7 +1379,9 @@ int dm_resume(struct mapped_device *md)
        if (!map || !dm_table_get_size(map))
                goto out;
 
-       dm_table_resume_targets(map);
+       r = dm_table_resume_targets(map);
+       if (r)
+               goto out;
 
        down_write(&md->io_lock);
        clear_bit(DMF_BLOCK_IO, &md->flags);
@@ -1337,6 +1399,8 @@ int dm_resume(struct mapped_device *md)
 
        dm_table_unplug_all(map);
 
+       kobject_uevent(&md->disk->kobj, KOBJ_CHANGE);
+
        r = 0;
 
 out:
@@ -1377,6 +1441,7 @@ int dm_suspended(struct mapped_device *md)
 static struct block_device_operations dm_blk_dops = {
        .open = dm_blk_open,
        .release = dm_blk_close,
+       .ioctl = dm_blk_ioctl,
        .getgeo = dm_blk_getgeo,
        .owner = THIS_MODULE
 };
index 3c03c0ecab7e4b9e9e31b0c00ff0661ce668a53b..a48ec5e3c1f478ea9523424f87b0db21fc8ab06d 100644 (file)
 #define DMERR(f, arg...) printk(KERN_ERR DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
 #define DMWARN(f, arg...) printk(KERN_WARNING DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
 #define DMINFO(f, arg...) printk(KERN_INFO DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
+#ifdef CONFIG_DM_DEBUG
+#  define DMDEBUG(f, arg...) printk(KERN_DEBUG DM_NAME ": " DM_MSG_PREFIX " DEBUG: " f "\n", ## arg)
+#else
+#  define DMDEBUG(f, arg...) do {} while (0)
+#endif
 
 #define DMEMIT(x...) sz += ((sz >= maxlen) ? \
                          0 : scnprintf(result + sz, maxlen - sz, x))
@@ -52,7 +57,7 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q);
 struct list_head *dm_table_get_devices(struct dm_table *t);
 void dm_table_presuspend_targets(struct dm_table *t);
 void dm_table_postsuspend_targets(struct dm_table *t);
-void dm_table_resume_targets(struct dm_table *t);
+int dm_table_resume_targets(struct dm_table *t);
 int dm_table_any_congested(struct dm_table *t, int bdi_bits);
 void dm_table_unplug_all(struct dm_table *t);
 int dm_table_flush_all(struct dm_table *t);
index b99c19c7eb2237e6f6583530c849bcfcaa2887c2..c625ddb8833d8b2de3f3d937b899e67b42cb48ae 100644 (file)
@@ -111,6 +111,19 @@ static int linear_issue_flush(request_queue_t *q, struct gendisk *disk,
        return ret;
 }
 
+static int linear_congested(void *data, int bits)
+{
+       mddev_t *mddev = data;
+       linear_conf_t *conf = mddev_to_conf(mddev);
+       int i, ret = 0;
+
+       for (i = 0; i < mddev->raid_disks && !ret ; i++) {
+               request_queue_t *q = bdev_get_queue(conf->disks[i].rdev->bdev);
+               ret |= bdi_congested(&q->backing_dev_info, bits);
+       }
+       return ret;
+}
+
 static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
 {
        linear_conf_t *conf;
@@ -269,6 +282,8 @@ static int linear_run (mddev_t *mddev)
        blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec);
        mddev->queue->unplug_fn = linear_unplug;
        mddev->queue->issue_flush_fn = linear_issue_flush;
+       mddev->queue->backing_dev_info.congested_fn = linear_congested;
+       mddev->queue->backing_dev_info.congested_data = mddev;
        return 0;
 }
 
index 8dbab2ef38857f1f0cff938701869e3b067d7b44..cb8281605be8f7d23bbd0769309268b5f69d7c1a 100644 (file)
@@ -389,8 +389,12 @@ static int super_written(struct bio *bio, unsigned int bytes_done, int error)
        if (bio->bi_size)
                return 1;
 
-       if (error || !test_bit(BIO_UPTODATE, &bio->bi_flags))
+       if (error || !test_bit(BIO_UPTODATE, &bio->bi_flags)) {
+               printk("md: super_written gets error=%d, uptodate=%d\n",
+                      error, test_bit(BIO_UPTODATE, &bio->bi_flags));
+               WARN_ON(test_bit(BIO_UPTODATE, &bio->bi_flags));
                md_error(mddev, rdev);
+       }
 
        if (atomic_dec_and_test(&mddev->pending_writes))
                wake_up(&mddev->sb_wait);
@@ -1587,7 +1591,7 @@ static void sync_sbs(mddev_t * mddev, int nospares)
        }
 }
 
-void md_update_sb(mddev_t * mddev)
+static void md_update_sb(mddev_t * mddev, int force_change)
 {
        int err;
        struct list_head *tmp;
@@ -1598,7 +1602,18 @@ void md_update_sb(mddev_t * mddev)
 repeat:
        spin_lock_irq(&mddev->write_lock);
 
-       if (mddev->degraded && mddev->sb_dirty == 3)
+       set_bit(MD_CHANGE_PENDING, &mddev->flags);
+       if (test_and_clear_bit(MD_CHANGE_DEVS, &mddev->flags))
+               force_change = 1;
+       if (test_and_clear_bit(MD_CHANGE_CLEAN, &mddev->flags))
+               /* just a clean<-> dirty transition, possibly leave spares alone,
+                * though if events isn't the right even/odd, we will have to do
+                * spares after all
+                */
+               nospares = 1;
+       if (force_change)
+               nospares = 0;
+       if (mddev->degraded)
                /* If the array is degraded, then skipping spares is both
                 * dangerous and fairly pointless.
                 * Dangerous because a device that was removed from the array
@@ -1608,20 +1623,14 @@ repeat:
                 * then a recovery will happen and soon that array won't
                 * be degraded any more and the spare can go back to sleep then.
                 */
-               mddev->sb_dirty = 1;
+               nospares = 0;
 
        sync_req = mddev->in_sync;
        mddev->utime = get_seconds();
-       if (mddev->sb_dirty == 3)
-               /* just a clean<-> dirty transition, possibly leave spares alone,
-                * though if events isn't the right even/odd, we will have to do
-                * spares after all
-                */
-               nospares = 1;
 
        /* If this is just a dirty<->clean transition, and the array is clean
         * and 'events' is odd, we can roll back to the previous clean state */
-       if (mddev->sb_dirty == 3
+       if (nospares
            && (mddev->in_sync && mddev->recovery_cp == MaxSector)
            && (mddev->events & 1))
                mddev->events--;
@@ -1652,7 +1661,6 @@ repeat:
                MD_BUG();
                mddev->events --;
        }
-       mddev->sb_dirty = 2;
        sync_sbs(mddev, nospares);
 
        /*
@@ -1660,7 +1668,7 @@ repeat:
         * nonpersistent superblocks
         */
        if (!mddev->persistent) {
-               mddev->sb_dirty = 0;
+               clear_bit(MD_CHANGE_PENDING, &mddev->flags);
                spin_unlock_irq(&mddev->write_lock);
                wake_up(&mddev->sb_wait);
                return;
@@ -1697,20 +1705,20 @@ repeat:
                        break;
        }
        md_super_wait(mddev);
-       /* if there was a failure, sb_dirty was set to 1, and we re-write super */
+       /* if there was a failure, MD_CHANGE_DEVS was set, and we re-write super */
 
        spin_lock_irq(&mddev->write_lock);
-       if (mddev->in_sync != sync_req|| mddev->sb_dirty == 1) {
+       if (mddev->in_sync != sync_req ||
+           test_bit(MD_CHANGE_DEVS, &mddev->flags)) {
                /* have to write it out again */
                spin_unlock_irq(&mddev->write_lock);
                goto repeat;
        }
-       mddev->sb_dirty = 0;
+       clear_bit(MD_CHANGE_PENDING, &mddev->flags);
        spin_unlock_irq(&mddev->write_lock);
        wake_up(&mddev->sb_wait);
 
 }
-EXPORT_SYMBOL_GPL(md_update_sb);
 
 /* words written to sysfs files may, or my not, be \n terminated.
  * We want to accept with case. For this we use cmd_match.
@@ -1783,7 +1791,7 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len)
                else {
                        mddev_t *mddev = rdev->mddev;
                        kick_rdev_from_array(rdev);
-                       md_update_sb(mddev);
+                       md_update_sb(mddev, 1);
                        md_new_event(mddev);
                        err = 0;
                }
@@ -2426,7 +2434,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
                        spin_lock_irq(&mddev->write_lock);
                        if (atomic_read(&mddev->writes_pending) == 0) {
                                mddev->in_sync = 1;
-                               mddev->sb_dirty = 1;
+                               set_bit(MD_CHANGE_CLEAN, &mddev->flags);
                        }
                        spin_unlock_irq(&mddev->write_lock);
                } else {
@@ -2438,7 +2446,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
        case active:
                if (mddev->pers) {
                        restart_array(mddev);
-                       mddev->sb_dirty = 0;
+                       clear_bit(MD_CHANGE_CLEAN, &mddev->flags);
                        wake_up(&mddev->sb_wait);
                        err = 0;
                } else {
@@ -2519,6 +2527,36 @@ new_dev_store(mddev_t *mddev, const char *buf, size_t len)
 static struct md_sysfs_entry md_new_device =
 __ATTR(new_dev, S_IWUSR, null_show, new_dev_store);
 
+static ssize_t
+bitmap_store(mddev_t *mddev, const char *buf, size_t len)
+{
+       char *end;
+       unsigned long chunk, end_chunk;
+
+       if (!mddev->bitmap)
+               goto out;
+       /* buf should be <chunk> <chunk> ... or <chunk>-<chunk> ... (range) */
+       while (*buf) {
+               chunk = end_chunk = simple_strtoul(buf, &end, 0);
+               if (buf == end) break;
+               if (*end == '-') { /* range */
+                       buf = end + 1;
+                       end_chunk = simple_strtoul(buf, &end, 0);
+                       if (buf == end) break;
+               }
+               if (*end && !isspace(*end)) break;
+               bitmap_dirty_bits(mddev->bitmap, chunk, end_chunk);
+               buf = end;
+               while (isspace(*buf)) buf++;
+       }
+       bitmap_unplug(mddev->bitmap); /* flush the bits to disk */
+out:
+       return len;
+}
+
+static struct md_sysfs_entry md_bitmap =
+__ATTR(bitmap_set_bits, S_IWUSR, null_show, bitmap_store);
+
 static ssize_t
 size_show(mddev_t *mddev, char *page)
 {
@@ -2543,7 +2581,7 @@ size_store(mddev_t *mddev, const char *buf, size_t len)
 
        if (mddev->pers) {
                err = update_size(mddev, size);
-               md_update_sb(mddev);
+               md_update_sb(mddev, 1);
        } else {
                if (mddev->size == 0 ||
                    mddev->size > size)
@@ -2839,6 +2877,7 @@ static struct attribute *md_redundancy_attrs[] = {
        &md_sync_completed.attr,
        &md_suspend_lo.attr,
        &md_suspend_hi.attr,
+       &md_bitmap.attr,
        NULL,
 };
 static struct attribute_group md_redundancy_group = {
@@ -3111,8 +3150,8 @@ static int do_md_run(mddev_t * mddev)
        
        set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
        
-       if (mddev->sb_dirty)
-               md_update_sb(mddev);
+       if (mddev->flags)
+               md_update_sb(mddev, 0);
 
        set_capacity(disk, mddev->array_size<<1);
 
@@ -3275,10 +3314,10 @@ static int do_md_stop(mddev_t * mddev, int mode)
                        if (mddev->ro)
                                mddev->ro = 0;
                }
-               if (!mddev->in_sync || mddev->sb_dirty) {
+               if (!mddev->in_sync || mddev->flags) {
                        /* mark array as shutdown cleanly */
                        mddev->in_sync = 1;
-                       md_update_sb(mddev);
+                       md_update_sb(mddev, 1);
                }
                if (mode == 1)
                        set_disk_ro(disk, 1);
@@ -3374,6 +3413,7 @@ static void autorun_devices(int part)
 
        printk(KERN_INFO "md: autorun ...\n");
        while (!list_empty(&pending_raid_disks)) {
+               int unit;
                dev_t dev;
                LIST_HEAD(candidates);
                rdev0 = list_entry(pending_raid_disks.next,
@@ -3393,16 +3433,19 @@ static void autorun_devices(int part)
                 * mostly sane superblocks. It's time to allocate the
                 * mddev.
                 */
-               if (rdev0->preferred_minor < 0 || rdev0->preferred_minor >= MAX_MD_DEVS) {
+               if (part) {
+                       dev = MKDEV(mdp_major,
+                                   rdev0->preferred_minor << MdpMinorShift);
+                       unit = MINOR(dev) >> MdpMinorShift;
+               } else {
+                       dev = MKDEV(MD_MAJOR, rdev0->preferred_minor);
+                       unit = MINOR(dev);
+               }
+               if (rdev0->preferred_minor != unit) {
                        printk(KERN_INFO "md: unit number in %s is bad: %d\n",
                               bdevname(rdev0->bdev, b), rdev0->preferred_minor);
                        break;
                }
-               if (part)
-                       dev = MKDEV(mdp_major,
-                                   rdev0->preferred_minor << MdpMinorShift);
-               else
-                       dev = MKDEV(MD_MAJOR, rdev0->preferred_minor);
 
                md_probe(dev, NULL, NULL);
                mddev = mddev_find(dev);
@@ -3440,67 +3483,6 @@ static void autorun_devices(int part)
        printk(KERN_INFO "md: ... autorun DONE.\n");
 }
 
-/*
- * import RAID devices based on one partition
- * if possible, the array gets run as well.
- */
-
-static int autostart_array(dev_t startdev)
-{
-       char b[BDEVNAME_SIZE];
-       int err = -EINVAL, i;
-       mdp_super_t *sb = NULL;
-       mdk_rdev_t *start_rdev = NULL, *rdev;
-
-       start_rdev = md_import_device(startdev, 0, 0);
-       if (IS_ERR(start_rdev))
-               return err;
-
-
-       /* NOTE: this can only work for 0.90.0 superblocks */
-       sb = (mdp_super_t*)page_address(start_rdev->sb_page);
-       if (sb->major_version != 0 ||
-           sb->minor_version != 90 ) {
-               printk(KERN_WARNING "md: can only autostart 0.90.0 arrays\n");
-               export_rdev(start_rdev);
-               return err;
-       }
-
-       if (test_bit(Faulty, &start_rdev->flags)) {
-               printk(KERN_WARNING 
-                       "md: can not autostart based on faulty %s!\n",
-                       bdevname(start_rdev->bdev,b));
-               export_rdev(start_rdev);
-               return err;
-       }
-       list_add(&start_rdev->same_set, &pending_raid_disks);
-
-       for (i = 0; i < MD_SB_DISKS; i++) {
-               mdp_disk_t *desc = sb->disks + i;
-               dev_t dev = MKDEV(desc->major, desc->minor);
-
-               if (!dev)
-                       continue;
-               if (dev == startdev)
-                       continue;
-               if (MAJOR(dev) != desc->major || MINOR(dev) != desc->minor)
-                       continue;
-               rdev = md_import_device(dev, 0, 0);
-               if (IS_ERR(rdev))
-                       continue;
-
-               list_add(&rdev->same_set, &pending_raid_disks);
-       }
-
-       /*
-        * possibly return codes
-        */
-       autorun_devices(0);
-       return 0;
-
-}
-
-
 static int get_version(void __user * arg)
 {
        mdu_version_t ver;
@@ -3808,7 +3790,7 @@ static int hot_remove_disk(mddev_t * mddev, dev_t dev)
                goto busy;
 
        kick_rdev_from_array(rdev);
-       md_update_sb(mddev);
+       md_update_sb(mddev, 1);
        md_new_event(mddev);
 
        return 0;
@@ -3885,7 +3867,7 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
 
        rdev->raid_disk = -1;
 
-       md_update_sb(mddev);
+       md_update_sb(mddev, 1);
 
        /*
         * Kick recovery, maybe this spare has to be added to the
@@ -4016,7 +3998,8 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info)
 
        mddev->max_disks     = MD_SB_DISKS;
 
-       mddev->sb_dirty      = 1;
+       mddev->flags         = 0;
+       set_bit(MD_CHANGE_DEVS, &mddev->flags);
 
        mddev->default_bitmap_offset = MD_SB_BYTES >> 9;
        mddev->bitmap_offset = 0;
@@ -4185,7 +4168,7 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info)
                        mddev->bitmap_offset = 0;
                }
        }
-       md_update_sb(mddev);
+       md_update_sb(mddev, 1);
        return rv;
 }
 
@@ -4259,27 +4242,6 @@ static int md_ioctl(struct inode *inode, struct file *file,
                goto abort;
        }
 
-
-       if (cmd == START_ARRAY) {
-               /* START_ARRAY doesn't need to lock the array as autostart_array
-                * does the locking, and it could even be a different array
-                */
-               static int cnt = 3;
-               if (cnt > 0 ) {
-                       printk(KERN_WARNING
-                              "md: %s(pid %d) used deprecated START_ARRAY ioctl. "
-                              "This will not be supported beyond July 2006\n",
-                              current->comm, current->pid);
-                       cnt--;
-               }
-               err = autostart_array(new_decode_dev(arg));
-               if (err) {
-                       printk(KERN_WARNING "md: autostart failed!\n");
-                       goto abort;
-               }
-               goto done;
-       }
-
        err = mddev_lock(mddev);
        if (err) {
                printk(KERN_INFO 
@@ -4476,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;
@@ -4687,9 +4648,11 @@ static void status_resync(struct seq_file *seq, mddev_t * mddev)
        seq_printf(seq, " %s =%3u.%u%% (%llu/%llu)",
                   (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)?
                    "reshape" :
-                     (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) ?
-                      "resync" : "recovery")),
-                     per_milli/10, per_milli % 10,
+                   (test_bit(MD_RECOVERY_CHECK, &mddev->recovery)?
+                    "check" :
+                    (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) ?
+                     "resync" : "recovery"))),
+                  per_milli/10, per_milli % 10,
                   (unsigned long long) resync,
                   (unsigned long long) max_blocks);
 
@@ -5042,12 +5005,12 @@ void md_write_start(mddev_t *mddev, struct bio *bi)
                spin_lock_irq(&mddev->write_lock);
                if (mddev->in_sync) {
                        mddev->in_sync = 0;
-                       mddev->sb_dirty = 3;
+                       set_bit(MD_CHANGE_CLEAN, &mddev->flags);
                        md_wakeup_thread(mddev->thread);
                }
                spin_unlock_irq(&mddev->write_lock);
        }
-       wait_event(mddev->sb_wait, mddev->sb_dirty==0);
+       wait_event(mddev->sb_wait, mddev->flags==0);
 }
 
 void md_write_end(mddev_t *mddev)
@@ -5078,6 +5041,7 @@ void md_do_sync(mddev_t *mddev)
        int skipped = 0;
        struct list_head *rtmp;
        mdk_rdev_t *rdev;
+       char *desc;
 
        /* just incase thread restarts... */
        if (test_bit(MD_RECOVERY_DONE, &mddev->recovery))
@@ -5085,6 +5049,18 @@ void md_do_sync(mddev_t *mddev)
        if (mddev->ro) /* never try to sync a read-only array */
                return;
 
+       if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
+               if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery))
+                       desc = "data-check";
+               else if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
+                       desc = "requested-resync";
+               else
+                       desc = "resync";
+       } else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
+               desc = "reshape";
+       else
+               desc = "recovery";
+
        /* we overload curr_resync somewhat here.
         * 0 == not engaged in resync at all
         * 2 == checking that there is no conflict with another sync
@@ -5128,10 +5104,10 @@ void md_do_sync(mddev_t *mddev)
                                prepare_to_wait(&resync_wait, &wq, TASK_UNINTERRUPTIBLE);
                                if (!kthread_should_stop() &&
                                    mddev2->curr_resync >= mddev->curr_resync) {
-                                       printk(KERN_INFO "md: delaying resync of %s"
-                                              " until %s has finished resync (they"
+                                       printk(KERN_INFO "md: delaying %s of %s"
+                                              " until %s has finished (they"
                                               " share one or more physical units)\n",
-                                              mdname(mddev), mdname(mddev2));
+                                              desc, mdname(mddev), mdname(mddev2));
                                        mddev_put(mddev2);
                                        schedule();
                                        finish_wait(&resync_wait, &wq);
@@ -5167,12 +5143,12 @@ void md_do_sync(mddev_t *mddev)
                                j = rdev->recovery_offset;
        }
 
-       printk(KERN_INFO "md: syncing RAID array %s\n", mdname(mddev));
-       printk(KERN_INFO "md: minimum _guaranteed_ reconstruction speed:"
-               " %d KB/sec/disc.\n", speed_min(mddev));
+       printk(KERN_INFO "md: %s of RAID array %s\n", desc, mdname(mddev));
+       printk(KERN_INFO "md: minimum _guaranteed_  speed:"
+               " %d KB/sec/disk.\n", speed_min(mddev));
        printk(KERN_INFO "md: using maximum available idle IO bandwidth "
-              "(but not more than %d KB/sec) for reconstruction.\n",
-              speed_max(mddev));
+              "(but not more than %d KB/sec) for %s.\n",
+              speed_max(mddev), desc);
 
        is_mddev_idle(mddev); /* this also initializes IO event counters */
 
@@ -5198,8 +5174,8 @@ void md_do_sync(mddev_t *mddev)
 
        if (j>2) {
                printk(KERN_INFO 
-                       "md: resuming recovery of %s from checkpoint.\n",
-                       mdname(mddev));
+                      "md: resuming %s of %s from checkpoint.\n",
+                      desc, mdname(mddev));
                mddev->curr_resync = j;
        }
 
@@ -5282,7 +5258,7 @@ void md_do_sync(mddev_t *mddev)
                        }
                }
        }
-       printk(KERN_INFO "md: %s: sync done.\n",mdname(mddev));
+       printk(KERN_INFO "md: %s: %s done.\n",mdname(mddev), desc);
        /*
         * this also signals 'finished resyncing' to md_stop
         */
@@ -5302,8 +5278,8 @@ void md_do_sync(mddev_t *mddev)
                        if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) {
                                if (mddev->curr_resync >= mddev->recovery_cp) {
                                        printk(KERN_INFO
-                                              "md: checkpointing recovery of %s.\n",
-                                              mdname(mddev));
+                                              "md: checkpointing %s of %s.\n",
+                                              desc, mdname(mddev));
                                        mddev->recovery_cp = mddev->curr_resync;
                                }
                        } else
@@ -5317,7 +5293,6 @@ void md_do_sync(mddev_t *mddev)
                                    !test_bit(In_sync, &rdev->flags) &&
                                    rdev->recovery_offset < mddev->curr_resync)
                                        rdev->recovery_offset = mddev->curr_resync;
-                       mddev->sb_dirty = 1;
                }
        }
 
@@ -5374,7 +5349,7 @@ void md_check_recovery(mddev_t *mddev)
        }
 
        if ( ! (
-               mddev->sb_dirty ||
+               mddev->flags ||
                test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) ||
                test_bit(MD_RECOVERY_DONE, &mddev->recovery) ||
                (mddev->safemode == 1) ||
@@ -5390,14 +5365,14 @@ void md_check_recovery(mddev_t *mddev)
                if (mddev->safemode && !atomic_read(&mddev->writes_pending) &&
                    !mddev->in_sync && mddev->recovery_cp == MaxSector) {
                        mddev->in_sync = 1;
-                       mddev->sb_dirty = 3;
+                       set_bit(MD_CHANGE_CLEAN, &mddev->flags);
                }
                if (mddev->safemode == 1)
                        mddev->safemode = 0;
                spin_unlock_irq(&mddev->write_lock);
 
-               if (mddev->sb_dirty)
-                       md_update_sb(mddev);
+               if (mddev->flags)
+                       md_update_sb(mddev, 0);
 
 
                if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) &&
@@ -5416,7 +5391,7 @@ void md_check_recovery(mddev_t *mddev)
                                /* activate any spares */
                                mddev->pers->spare_active(mddev);
                        }
-                       md_update_sb(mddev);
+                       md_update_sb(mddev, 1);
 
                        /* if array is no-longer degraded, then any saved_raid_disk
                         * information must be scrapped
@@ -5556,22 +5531,15 @@ static void md_geninit(void)
 
 static int __init md_init(void)
 {
-       printk(KERN_INFO "md: md driver %d.%d.%d MAX_MD_DEVS=%d,"
-                       " MD_SB_DISKS=%d\n",
-                       MD_MAJOR_VERSION, MD_MINOR_VERSION,
-                       MD_PATCHLEVEL_VERSION, MAX_MD_DEVS, MD_SB_DISKS);
-       printk(KERN_INFO "md: bitmap version %d.%d\n", BITMAP_MAJOR_HI,
-                       BITMAP_MINOR);
-
        if (register_blkdev(MAJOR_NR, "md"))
                return -1;
        if ((mdp_major=register_blkdev(0, "mdp"))<=0) {
                unregister_blkdev(MAJOR_NR, "md");
                return -1;
        }
-       blk_register_region(MKDEV(MAJOR_NR, 0), MAX_MD_DEVS, THIS_MODULE,
-                               md_probe, NULL, NULL);
-       blk_register_region(MKDEV(mdp_major, 0), MAX_MD_DEVS<<MdpMinorShift, THIS_MODULE,
+       blk_register_region(MKDEV(MAJOR_NR, 0), 1UL<<MINORBITS, THIS_MODULE,
+                           md_probe, NULL, NULL);
+       blk_register_region(MKDEV(mdp_major, 0), 1UL<<MINORBITS, THIS_MODULE,
                            md_probe, NULL, NULL);
 
        register_reboot_notifier(&md_notifier);
@@ -5630,8 +5598,8 @@ static __exit void md_exit(void)
        mddev_t *mddev;
        struct list_head *tmp;
 
-       blk_unregister_region(MKDEV(MAJOR_NR,0), MAX_MD_DEVS);
-       blk_unregister_region(MKDEV(mdp_major,0), MAX_MD_DEVS << MdpMinorShift);
+       blk_unregister_region(MKDEV(MAJOR_NR,0), 1U << MINORBITS);
+       blk_unregister_region(MKDEV(mdp_major,0), 1U << MINORBITS);
 
        unregister_blkdev(MAJOR_NR,"md");
        unregister_blkdev(mdp_major, "mdp");
index 1cc9de44ce86c2cce64c58fb72d8b3f33245a83f..171ff41b52b053e7acdc2f6c78e0ef34ed2bd695 100644 (file)
@@ -228,6 +228,28 @@ static int multipath_issue_flush(request_queue_t *q, struct gendisk *disk,
        rcu_read_unlock();
        return ret;
 }
+static int multipath_congested(void *data, int bits)
+{
+       mddev_t *mddev = data;
+       multipath_conf_t *conf = mddev_to_conf(mddev);
+       int i, ret = 0;
+
+       rcu_read_lock();
+       for (i = 0; i < mddev->raid_disks ; i++) {
+               mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev);
+               if (rdev && !test_bit(Faulty, &rdev->flags)) {
+                       request_queue_t *q = bdev_get_queue(rdev->bdev);
+
+                       ret |= bdi_congested(&q->backing_dev_info, bits);
+                       /* Just like multipath_map, we just check the
+                        * first available device
+                        */
+                       break;
+               }
+       }
+       rcu_read_unlock();
+       return ret;
+}
 
 /*
  * Careful, this can execute in IRQ contexts as well!
@@ -253,7 +275,7 @@ static void multipath_error (mddev_t *mddev, mdk_rdev_t *rdev)
                        char b[BDEVNAME_SIZE];
                        clear_bit(In_sync, &rdev->flags);
                        set_bit(Faulty, &rdev->flags);
-                       mddev->sb_dirty = 1;
+                       set_bit(MD_CHANGE_DEVS, &mddev->flags);
                        conf->working_disks--;
                        printk(KERN_ALERT "multipath: IO failure on %s,"
                                " disabling IO path. \n Operation continuing"
@@ -470,7 +492,6 @@ static int multipath_run (mddev_t *mddev)
        }
 
        conf->raid_disks = mddev->raid_disks;
-       mddev->sb_dirty = 1;
        conf->mddev = mddev;
        spin_lock_init(&conf->device_lock);
        INIT_LIST_HEAD(&conf->retry_list);
@@ -510,6 +531,8 @@ static int multipath_run (mddev_t *mddev)
 
        mddev->queue->unplug_fn = multipath_unplug;
        mddev->queue->issue_flush_fn = multipath_issue_flush;
+       mddev->queue->backing_dev_info.congested_fn = multipath_congested;
+       mddev->queue->backing_dev_info.congested_data = mddev;
 
        return 0;
 
index cb8c6317e4e5fc367c7098a87e310b5ed059f724..dfe32149ad3ae1b0caf77fc39003d82cb640f3f7 100644 (file)
@@ -60,6 +60,21 @@ static int raid0_issue_flush(request_queue_t *q, struct gendisk *disk,
        return ret;
 }
 
+static int raid0_congested(void *data, int bits)
+{
+       mddev_t *mddev = data;
+       raid0_conf_t *conf = mddev_to_conf(mddev);
+       mdk_rdev_t **devlist = conf->strip_zone[0].dev;
+       int i, ret = 0;
+
+       for (i = 0; i < mddev->raid_disks && !ret ; i++) {
+               request_queue_t *q = bdev_get_queue(devlist[i]->bdev);
+
+               ret |= bdi_congested(&q->backing_dev_info, bits);
+       }
+       return ret;
+}
+
 
 static int create_strip_zones (mddev_t *mddev)
 {
@@ -236,6 +251,8 @@ static int create_strip_zones (mddev_t *mddev)
        mddev->queue->unplug_fn = raid0_unplug;
 
        mddev->queue->issue_flush_fn = raid0_issue_flush;
+       mddev->queue->backing_dev_info.congested_fn = raid0_congested;
+       mddev->queue->backing_dev_info.congested_data = mddev;
 
        printk("raid0: done.\n");
        return 0;
index 3b4d69c0562301b18039657ac0d47261a4eed6af..dc9d2def0270df7460a4eb0e20c4cf494ae94319 100644 (file)
@@ -271,7 +271,7 @@ static int raid1_end_read_request(struct bio *bio, unsigned int bytes_done, int
         */
        update_head_pos(mirror, r1_bio);
 
-       if (uptodate || conf->working_disks <= 1) {
+       if (uptodate || (conf->raid_disks - conf->mddev->degraded) <= 1) {
                /*
                 * Set R1BIO_Uptodate in our master bio, so that
                 * we will return a good error code for to the higher
@@ -601,6 +601,32 @@ static int raid1_issue_flush(request_queue_t *q, struct gendisk *disk,
        return ret;
 }
 
+static int raid1_congested(void *data, int bits)
+{
+       mddev_t *mddev = data;
+       conf_t *conf = mddev_to_conf(mddev);
+       int i, ret = 0;
+
+       rcu_read_lock();
+       for (i = 0; i < mddev->raid_disks; i++) {
+               mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
+               if (rdev && !test_bit(Faulty, &rdev->flags)) {
+                       request_queue_t *q = bdev_get_queue(rdev->bdev);
+
+                       /* Note the '|| 1' - when read_balance prefers
+                        * non-congested targets, it can be removed
+                        */
+                       if ((bits & (1<<BDI_write_congested)) || 1)
+                               ret |= bdi_congested(&q->backing_dev_info, bits);
+                       else
+                               ret &= bdi_congested(&q->backing_dev_info, bits);
+               }
+       }
+       rcu_read_unlock();
+       return ret;
+}
+
+
 /* Barriers....
  * Sometimes we need to suspend IO while we do something else,
  * either some resync/recovery, or reconfigure the array.
@@ -929,7 +955,7 @@ static void status(struct seq_file *seq, mddev_t *mddev)
        int i;
 
        seq_printf(seq, " [%d/%d] [", conf->raid_disks,
-                                               conf->working_disks);
+                  conf->raid_disks - mddev->degraded);
        rcu_read_lock();
        for (i = 0; i < conf->raid_disks; i++) {
                mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
@@ -953,26 +979,27 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
         * else mark the drive as failed
         */
        if (test_bit(In_sync, &rdev->flags)
-           && conf->working_disks == 1)
+           && (conf->raid_disks - mddev->degraded) == 1)
                /*
                 * Don't fail the drive, act as though we were just a
                 * normal single drive
                 */
                return;
-       if (test_bit(In_sync, &rdev->flags)) {
+       if (test_and_clear_bit(In_sync, &rdev->flags)) {
+               unsigned long flags;
+               spin_lock_irqsave(&conf->device_lock, flags);
                mddev->degraded++;
-               conf->working_disks--;
+               spin_unlock_irqrestore(&conf->device_lock, flags);
                /*
                 * if recovery is running, make sure it aborts.
                 */
                set_bit(MD_RECOVERY_ERR, &mddev->recovery);
        }
-       clear_bit(In_sync, &rdev->flags);
        set_bit(Faulty, &rdev->flags);
-       mddev->sb_dirty = 1;
+       set_bit(MD_CHANGE_DEVS, &mddev->flags);
        printk(KERN_ALERT "raid1: Disk failure on %s, disabling device. \n"
                "       Operation continuing on %d devices\n",
-               bdevname(rdev->bdev,b), conf->working_disks);
+               bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded);
 }
 
 static void print_conf(conf_t *conf)
@@ -984,7 +1011,7 @@ static void print_conf(conf_t *conf)
                printk("(!conf)\n");
                return;
        }
-       printk(" --- wd:%d rd:%d\n", conf->working_disks,
+       printk(" --- wd:%d rd:%d\n", conf->raid_disks - conf->mddev->degraded,
                conf->raid_disks);
 
        rcu_read_lock();
@@ -1023,10 +1050,11 @@ static int raid1_spare_active(mddev_t *mddev)
                mdk_rdev_t *rdev = conf->mirrors[i].rdev;
                if (rdev
                    && !test_bit(Faulty, &rdev->flags)
-                   && !test_bit(In_sync, &rdev->flags)) {
-                       conf->working_disks++;
+                   && !test_and_set_bit(In_sync, &rdev->flags)) {
+                       unsigned long flags;
+                       spin_lock_irqsave(&conf->device_lock, flags);
                        mddev->degraded--;
-                       set_bit(In_sync, &rdev->flags);
+                       spin_unlock_irqrestore(&conf->device_lock, flags);
                }
        }
 
@@ -1368,6 +1396,95 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio)
  *     3.      Performs writes following reads for array syncronising.
  */
 
+static void fix_read_error(conf_t *conf, int read_disk,
+                          sector_t sect, int sectors)
+{
+       mddev_t *mddev = conf->mddev;
+       while(sectors) {
+               int s = sectors;
+               int d = read_disk;
+               int success = 0;
+               int start;
+               mdk_rdev_t *rdev;
+
+               if (s > (PAGE_SIZE>>9))
+                       s = PAGE_SIZE >> 9;
+
+               do {
+                       /* Note: no rcu protection needed here
+                        * as this is synchronous in the raid1d thread
+                        * which is the thread that might remove
+                        * a device.  If raid1d ever becomes multi-threaded....
+                        */
+                       rdev = conf->mirrors[d].rdev;
+                       if (rdev &&
+                           test_bit(In_sync, &rdev->flags) &&
+                           sync_page_io(rdev->bdev,
+                                        sect + rdev->data_offset,
+                                        s<<9,
+                                        conf->tmppage, READ))
+                               success = 1;
+                       else {
+                               d++;
+                               if (d == conf->raid_disks)
+                                       d = 0;
+                       }
+               } while (!success && d != read_disk);
+
+               if (!success) {
+                       /* Cannot read from anywhere -- bye bye array */
+                       md_error(mddev, conf->mirrors[read_disk].rdev);
+                       break;
+               }
+               /* write it back and re-read */
+               start = d;
+               while (d != read_disk) {
+                       if (d==0)
+                               d = conf->raid_disks;
+                       d--;
+                       rdev = conf->mirrors[d].rdev;
+                       if (rdev &&
+                           test_bit(In_sync, &rdev->flags)) {
+                               if (sync_page_io(rdev->bdev,
+                                                sect + rdev->data_offset,
+                                                s<<9, conf->tmppage, WRITE)
+                                   == 0)
+                                       /* Well, this device is dead */
+                                       md_error(mddev, rdev);
+                       }
+               }
+               d = start;
+               while (d != read_disk) {
+                       char b[BDEVNAME_SIZE];
+                       if (d==0)
+                               d = conf->raid_disks;
+                       d--;
+                       rdev = conf->mirrors[d].rdev;
+                       if (rdev &&
+                           test_bit(In_sync, &rdev->flags)) {
+                               if (sync_page_io(rdev->bdev,
+                                                sect + rdev->data_offset,
+                                                s<<9, conf->tmppage, READ)
+                                   == 0)
+                                       /* Well, this device is dead */
+                                       md_error(mddev, rdev);
+                               else {
+                                       atomic_add(s, &rdev->corrected_errors);
+                                       printk(KERN_INFO
+                                              "raid1:%s: read error corrected "
+                                              "(%d sectors at %llu on %s)\n",
+                                              mdname(mddev), s,
+                                              (unsigned long long)sect +
+                                                  rdev->data_offset,
+                                              bdevname(rdev->bdev, b));
+                               }
+                       }
+               }
+               sectors -= s;
+               sect += s;
+       }
+}
+
 static void raid1d(mddev_t *mddev)
 {
        r1bio_t *r1_bio;
@@ -1460,86 +1577,14 @@ static void raid1d(mddev_t *mddev)
                         * This is all done synchronously while the array is
                         * frozen
                         */
-                       sector_t sect = r1_bio->sector;
-                       int sectors = r1_bio->sectors;
-                       freeze_array(conf);
-                       if (mddev->ro == 0) while(sectors) {
-                               int s = sectors;
-                               int d = r1_bio->read_disk;
-                               int success = 0;
-
-                               if (s > (PAGE_SIZE>>9))
-                                       s = PAGE_SIZE >> 9;
-
-                               do {
-                                       /* Note: no rcu protection needed here
-                                        * as this is synchronous in the raid1d thread
-                                        * which is the thread that might remove
-                                        * a device.  If raid1d ever becomes multi-threaded....
-                                        */
-                                       rdev = conf->mirrors[d].rdev;
-                                       if (rdev &&
-                                           test_bit(In_sync, &rdev->flags) &&
-                                           sync_page_io(rdev->bdev,
-                                                        sect + rdev->data_offset,
-                                                        s<<9,
-                                                        conf->tmppage, READ))
-                                               success = 1;
-                                       else {
-                                               d++;
-                                               if (d == conf->raid_disks)
-                                                       d = 0;
-                                       }
-                               } while (!success && d != r1_bio->read_disk);
-
-                               if (success) {
-                                       /* write it back and re-read */
-                                       int start = d;
-                                       while (d != r1_bio->read_disk) {
-                                               if (d==0)
-                                                       d = conf->raid_disks;
-                                               d--;
-                                               rdev = conf->mirrors[d].rdev;
-                                               if (rdev &&
-                                                   test_bit(In_sync, &rdev->flags)) {
-                                                       if (sync_page_io(rdev->bdev,
-                                                                        sect + rdev->data_offset,
-                                                                        s<<9, conf->tmppage, WRITE) == 0)
-                                                               /* Well, this device is dead */
-                                                               md_error(mddev, rdev);
-                                               }
-                                       }
-                                       d = start;
-                                       while (d != r1_bio->read_disk) {
-                                               if (d==0)
-                                                       d = conf->raid_disks;
-                                               d--;
-                                               rdev = conf->mirrors[d].rdev;
-                                               if (rdev &&
-                                                   test_bit(In_sync, &rdev->flags)) {
-                                                       if (sync_page_io(rdev->bdev,
-                                                                        sect + rdev->data_offset,
-                                                                        s<<9, conf->tmppage, READ) == 0)
-                                                               /* Well, this device is dead */
-                                                               md_error(mddev, rdev);
-                                                       else {
-                                                               atomic_add(s, &rdev->corrected_errors);
-                                                               printk(KERN_INFO "raid1:%s: read error corrected (%d sectors at %llu on %s)\n",
-                                                                      mdname(mddev), s, (unsigned long long)(sect + rdev->data_offset), bdevname(rdev->bdev, b));
-                                                       }
-                                               }
-                                       }
-                               } else {
-                                       /* Cannot read from anywhere -- bye bye array */
-                                       md_error(mddev, conf->mirrors[r1_bio->read_disk].rdev);
-                                       break;
-                               }
-                               sectors -= s;
-                               sect += s;
+                       if (mddev->ro == 0) {
+                               freeze_array(conf);
+                               fix_read_error(conf, r1_bio->read_disk,
+                                              r1_bio->sector,
+                                              r1_bio->sectors);
+                               unfreeze_array(conf);
                        }
 
-                       unfreeze_array(conf);
-
                        bio = r1_bio->bios[r1_bio->read_disk];
                        if ((disk=read_balance(conf, r1_bio)) == -1) {
                                printk(KERN_ALERT "raid1: %s: unrecoverable I/O"
@@ -1884,15 +1929,11 @@ static int run(mddev_t *mddev)
                        blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
 
                disk->head_position = 0;
-               if (!test_bit(Faulty, &rdev->flags) && test_bit(In_sync, &rdev->flags))
-                       conf->working_disks++;
        }
        conf->raid_disks = mddev->raid_disks;
        conf->mddev = mddev;
        spin_lock_init(&conf->device_lock);
        INIT_LIST_HEAD(&conf->retry_list);
-       if (conf->working_disks == 1)
-               mddev->recovery_cp = MaxSector;
 
        spin_lock_init(&conf->resync_lock);
        init_waitqueue_head(&conf->wait_barrier);
@@ -1900,11 +1941,6 @@ static int run(mddev_t *mddev)
        bio_list_init(&conf->pending_bio_list);
        bio_list_init(&conf->flushing_bio_list);
 
-       if (!conf->working_disks) {
-               printk(KERN_ERR "raid1: no operational mirrors for %s\n",
-                       mdname(mddev));
-               goto out_free_conf;
-       }
 
        mddev->degraded = 0;
        for (i = 0; i < conf->raid_disks; i++) {
@@ -1917,6 +1953,13 @@ static int run(mddev_t *mddev)
                        mddev->degraded++;
                }
        }
+       if (mddev->degraded == conf->raid_disks) {
+               printk(KERN_ERR "raid1: no operational mirrors for %s\n",
+                       mdname(mddev));
+               goto out_free_conf;
+       }
+       if (conf->raid_disks - mddev->degraded == 1)
+               mddev->recovery_cp = MaxSector;
 
        /*
         * find the first working one and use it as a starting point
@@ -1948,6 +1991,8 @@ static int run(mddev_t *mddev)
 
        mddev->queue->unplug_fn = raid1_unplug;
        mddev->queue->issue_flush_fn = raid1_issue_flush;
+       mddev->queue->backing_dev_info.congested_fn = raid1_congested;
+       mddev->queue->backing_dev_info.congested_data = mddev;
 
        return 0;
 
@@ -2035,7 +2080,7 @@ static int raid1_reshape(mddev_t *mddev)
        mirror_info_t *newmirrors;
        conf_t *conf = mddev_to_conf(mddev);
        int cnt, raid_disks;
-
+       unsigned long flags;
        int d, d2;
 
        /* Cannot change chunk_size, layout, or level */
@@ -2094,7 +2139,9 @@ static int raid1_reshape(mddev_t *mddev)
        kfree(conf->poolinfo);
        conf->poolinfo = newpoolinfo;
 
+       spin_lock_irqsave(&conf->device_lock, flags);
        mddev->degraded += (raid_disks - conf->raid_disks);
+       spin_unlock_irqrestore(&conf->device_lock, flags);
        conf->raid_disks = mddev->raid_disks = raid_disks;
        mddev->delta_disks = 0;
 
index 016ddb831c9b393dfb44c52076dbcbc4f4750b96..1250f0eab4afaf7b2c946a3c3767c25efc062bfc 100644 (file)
@@ -648,6 +648,26 @@ static int raid10_issue_flush(request_queue_t *q, struct gendisk *disk,
        return ret;
 }
 
+static int raid10_congested(void *data, int bits)
+{
+       mddev_t *mddev = data;
+       conf_t *conf = mddev_to_conf(mddev);
+       int i, ret = 0;
+
+       rcu_read_lock();
+       for (i = 0; i < mddev->raid_disks && ret == 0; i++) {
+               mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
+               if (rdev && !test_bit(Faulty, &rdev->flags)) {
+                       request_queue_t *q = bdev_get_queue(rdev->bdev);
+
+                       ret |= bdi_congested(&q->backing_dev_info, bits);
+               }
+       }
+       rcu_read_unlock();
+       return ret;
+}
+
+
 /* Barriers....
  * Sometimes we need to suspend IO while we do something else,
  * either some resync/recovery, or reconfigure the array.
@@ -921,7 +941,7 @@ static void status(struct seq_file *seq, mddev_t *mddev)
                        seq_printf(seq, " %d far-copies", conf->far_copies);
        }
        seq_printf(seq, " [%d/%d] [", conf->raid_disks,
-                                               conf->working_disks);
+                                       conf->raid_disks - mddev->degraded);
        for (i = 0; i < conf->raid_disks; i++)
                seq_printf(seq, "%s",
                              conf->mirrors[i].rdev &&
@@ -941,7 +961,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
         * else mark the drive as failed
         */
        if (test_bit(In_sync, &rdev->flags)
-           && conf->working_disks == 1)
+           && conf->raid_disks-mddev->degraded == 1)
                /*
                 * Don't fail the drive, just return an IO error.
                 * The test should really be more sophisticated than
@@ -950,20 +970,21 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
                 * really dead" tests...
                 */
                return;
-       if (test_bit(In_sync, &rdev->flags)) {
+       if (test_and_clear_bit(In_sync, &rdev->flags)) {
+               unsigned long flags;
+               spin_lock_irqsave(&conf->device_lock, flags);
                mddev->degraded++;
-               conf->working_disks--;
+               spin_unlock_irqrestore(&conf->device_lock, flags);
                /*
                 * if recovery is running, make sure it aborts.
                 */
                set_bit(MD_RECOVERY_ERR, &mddev->recovery);
        }
-       clear_bit(In_sync, &rdev->flags);
        set_bit(Faulty, &rdev->flags);
-       mddev->sb_dirty = 1;
+       set_bit(MD_CHANGE_DEVS, &mddev->flags);
        printk(KERN_ALERT "raid10: Disk failure on %s, disabling device. \n"
                "       Operation continuing on %d devices\n",
-               bdevname(rdev->bdev,b), conf->working_disks);
+               bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded);
 }
 
 static void print_conf(conf_t *conf)
@@ -976,7 +997,7 @@ static void print_conf(conf_t *conf)
                printk("(!conf)\n");
                return;
        }
-       printk(" --- wd:%d rd:%d\n", conf->working_disks,
+       printk(" --- wd:%d rd:%d\n", conf->raid_disks - conf->mddev->degraded,
                conf->raid_disks);
 
        for (i = 0; i < conf->raid_disks; i++) {
@@ -1034,10 +1055,11 @@ static int raid10_spare_active(mddev_t *mddev)
                tmp = conf->mirrors + i;
                if (tmp->rdev
                    && !test_bit(Faulty, &tmp->rdev->flags)
-                   && !test_bit(In_sync, &tmp->rdev->flags)) {
-                       conf->working_disks++;
+                   && !test_and_set_bit(In_sync, &tmp->rdev->flags)) {
+                       unsigned long flags;
+                       spin_lock_irqsave(&conf->device_lock, flags);
                        mddev->degraded--;
-                       set_bit(In_sync, &tmp->rdev->flags);
+                       spin_unlock_irqrestore(&conf->device_lock, flags);
                }
        }
 
@@ -1350,9 +1372,119 @@ static void recovery_request_write(mddev_t *mddev, r10bio_t *r10_bio)
  *
  *     1.      Retries failed read operations on working mirrors.
  *     2.      Updates the raid superblock when problems encounter.
- *     3.      Performs writes following reads for array syncronising.
+ *     3.      Performs writes following reads for array synchronising.
  */
 
+static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio)
+{
+       int sect = 0; /* Offset from r10_bio->sector */
+       int sectors = r10_bio->sectors;
+       mdk_rdev_t*rdev;
+       while(sectors) {
+               int s = sectors;
+               int sl = r10_bio->read_slot;
+               int success = 0;
+               int start;
+
+               if (s > (PAGE_SIZE>>9))
+                       s = PAGE_SIZE >> 9;
+
+               rcu_read_lock();
+               do {
+                       int d = r10_bio->devs[sl].devnum;
+                       rdev = rcu_dereference(conf->mirrors[d].rdev);
+                       if (rdev &&
+                           test_bit(In_sync, &rdev->flags)) {
+                               atomic_inc(&rdev->nr_pending);
+                               rcu_read_unlock();
+                               success = sync_page_io(rdev->bdev,
+                                                      r10_bio->devs[sl].addr +
+                                                      sect + rdev->data_offset,
+                                                      s<<9,
+                                                      conf->tmppage, READ);
+                               rdev_dec_pending(rdev, mddev);
+                               rcu_read_lock();
+                               if (success)
+                                       break;
+                       }
+                       sl++;
+                       if (sl == conf->copies)
+                               sl = 0;
+               } while (!success && sl != r10_bio->read_slot);
+               rcu_read_unlock();
+
+               if (!success) {
+                       /* Cannot read from anywhere -- bye bye array */
+                       int dn = r10_bio->devs[r10_bio->read_slot].devnum;
+                       md_error(mddev, conf->mirrors[dn].rdev);
+                       break;
+               }
+
+               start = sl;
+               /* write it back and re-read */
+               rcu_read_lock();
+               while (sl != r10_bio->read_slot) {
+                       int d;
+                       if (sl==0)
+                               sl = conf->copies;
+                       sl--;
+                       d = r10_bio->devs[sl].devnum;
+                       rdev = rcu_dereference(conf->mirrors[d].rdev);
+                       if (rdev &&
+                           test_bit(In_sync, &rdev->flags)) {
+                               atomic_inc(&rdev->nr_pending);
+                               rcu_read_unlock();
+                               atomic_add(s, &rdev->corrected_errors);
+                               if (sync_page_io(rdev->bdev,
+                                                r10_bio->devs[sl].addr +
+                                                sect + rdev->data_offset,
+                                                s<<9, conf->tmppage, WRITE)
+                                   == 0)
+                                       /* Well, this device is dead */
+                                       md_error(mddev, rdev);
+                               rdev_dec_pending(rdev, mddev);
+                               rcu_read_lock();
+                       }
+               }
+               sl = start;
+               while (sl != r10_bio->read_slot) {
+                       int d;
+                       if (sl==0)
+                               sl = conf->copies;
+                       sl--;
+                       d = r10_bio->devs[sl].devnum;
+                       rdev = rcu_dereference(conf->mirrors[d].rdev);
+                       if (rdev &&
+                           test_bit(In_sync, &rdev->flags)) {
+                               char b[BDEVNAME_SIZE];
+                               atomic_inc(&rdev->nr_pending);
+                               rcu_read_unlock();
+                               if (sync_page_io(rdev->bdev,
+                                                r10_bio->devs[sl].addr +
+                                                sect + rdev->data_offset,
+                                                s<<9, conf->tmppage, READ) == 0)
+                                       /* Well, this device is dead */
+                                       md_error(mddev, rdev);
+                               else
+                                       printk(KERN_INFO
+                                              "raid10:%s: read error corrected"
+                                              " (%d sectors at %llu on %s)\n",
+                                              mdname(mddev), s,
+                                              (unsigned long long)sect+
+                                                   rdev->data_offset,
+                                              bdevname(rdev->bdev, b));
+
+                               rdev_dec_pending(rdev, mddev);
+                               rcu_read_lock();
+                       }
+               }
+               rcu_read_unlock();
+
+               sectors -= s;
+               sect += s;
+       }
+}
+
 static void raid10d(mddev_t *mddev)
 {
        r10bio_t *r10_bio;
@@ -1413,105 +1545,12 @@ static void raid10d(mddev_t *mddev)
                         * This is all done synchronously while the array is
                         * frozen.
                         */
-                       int sect = 0; /* Offset from r10_bio->sector */
-                       int sectors = r10_bio->sectors;
-                       freeze_array(conf);
-                       if (mddev->ro == 0) while(sectors) {
-                               int s = sectors;
-                               int sl = r10_bio->read_slot;
-                               int success = 0;
-
-                               if (s > (PAGE_SIZE>>9))
-                                       s = PAGE_SIZE >> 9;
-
-                               rcu_read_lock();
-                               do {
-                                       int d = r10_bio->devs[sl].devnum;
-                                       rdev = rcu_dereference(conf->mirrors[d].rdev);
-                                       if (rdev &&
-                                           test_bit(In_sync, &rdev->flags)) {
-                                               atomic_inc(&rdev->nr_pending);
-                                               rcu_read_unlock();
-                                               success = sync_page_io(rdev->bdev,
-                                                                      r10_bio->devs[sl].addr +
-                                                                      sect + rdev->data_offset,
-                                                                      s<<9,
-                                                                      conf->tmppage, READ);
-                                               rdev_dec_pending(rdev, mddev);
-                                               rcu_read_lock();
-                                               if (success)
-                                                       break;
-                                       }
-                                       sl++;
-                                       if (sl == conf->copies)
-                                               sl = 0;
-                               } while (!success && sl != r10_bio->read_slot);
-                               rcu_read_unlock();
-
-                               if (success) {
-                                       int start = sl;
-                                       /* write it back and re-read */
-                                       rcu_read_lock();
-                                       while (sl != r10_bio->read_slot) {
-                                               int d;
-                                               if (sl==0)
-                                                       sl = conf->copies;
-                                               sl--;
-                                               d = r10_bio->devs[sl].devnum;
-                                               rdev = rcu_dereference(conf->mirrors[d].rdev);
-                                               if (rdev &&
-                                                   test_bit(In_sync, &rdev->flags)) {
-                                                       atomic_inc(&rdev->nr_pending);
-                                                       rcu_read_unlock();
-                                                       atomic_add(s, &rdev->corrected_errors);
-                                                       if (sync_page_io(rdev->bdev,
-                                                                        r10_bio->devs[sl].addr +
-                                                                        sect + rdev->data_offset,
-                                                                        s<<9, conf->tmppage, WRITE) == 0)
-                                                               /* Well, this device is dead */
-                                                               md_error(mddev, rdev);
-                                                       rdev_dec_pending(rdev, mddev);
-                                                       rcu_read_lock();
-                                               }
-                                       }
-                                       sl = start;
-                                       while (sl != r10_bio->read_slot) {
-                                               int d;
-                                               if (sl==0)
-                                                       sl = conf->copies;
-                                               sl--;
-                                               d = r10_bio->devs[sl].devnum;
-                                               rdev = rcu_dereference(conf->mirrors[d].rdev);
-                                               if (rdev &&
-                                                   test_bit(In_sync, &rdev->flags)) {
-                                                       atomic_inc(&rdev->nr_pending);
-                                                       rcu_read_unlock();
-                                                       if (sync_page_io(rdev->bdev,
-                                                                        r10_bio->devs[sl].addr +
-                                                                        sect + rdev->data_offset,
-                                                                        s<<9, conf->tmppage, READ) == 0)
-                                                               /* Well, this device is dead */
-                                                               md_error(mddev, rdev);
-                                                       else
-                                                               printk(KERN_INFO "raid10:%s: read error corrected (%d sectors at %llu on %s)\n",
-                                                                      mdname(mddev), s, (unsigned long long)(sect+rdev->data_offset), bdevname(rdev->bdev, b));
-
-                                                       rdev_dec_pending(rdev, mddev);
-                                                       rcu_read_lock();
-                                               }
-                                       }
-                                       rcu_read_unlock();
-                               } else {
-                                       /* Cannot read from anywhere -- bye bye array */
-                                       md_error(mddev, conf->mirrors[r10_bio->devs[r10_bio->read_slot].devnum].rdev);
-                                       break;
-                               }
-                               sectors -= s;
-                               sect += s;
+                       if (mddev->ro == 0) {
+                               freeze_array(conf);
+                               fix_read_error(conf, mddev, r10_bio);
+                               unfreeze_array(conf);
                        }
 
-                       unfreeze_array(conf);
-
                        bio = r10_bio->devs[r10_bio->read_slot].bio;
                        r10_bio->devs[r10_bio->read_slot].bio =
                                mddev->ro ? IO_BLOCKED : NULL;
@@ -2018,8 +2057,6 @@ static int run(mddev_t *mddev)
                        mddev->queue->max_sectors = (PAGE_SIZE>>9);
 
                disk->head_position = 0;
-               if (!test_bit(Faulty, &rdev->flags) && test_bit(In_sync, &rdev->flags))
-                       conf->working_disks++;
        }
        conf->raid_disks = mddev->raid_disks;
        conf->mddev = mddev;
@@ -2077,6 +2114,8 @@ static int run(mddev_t *mddev)
 
        mddev->queue->unplug_fn = raid10_unplug;
        mddev->queue->issue_flush_fn = raid10_issue_flush;
+       mddev->queue->backing_dev_info.congested_fn = raid10_congested;
+       mddev->queue->backing_dev_info.congested_data = mddev;
 
        /* Calculate max read-ahead size.
         * We need to readahead at least twice a whole stripe....
index 450066007160ca04d1a8956abe870bc1b363210a..e14f4578072006e3b464668d3c8500187df76453 100644 (file)
@@ -636,7 +636,6 @@ static int raid5_end_write_request (struct bio *bi, unsigned int bytes_done,
        struct stripe_head *sh = bi->bi_private;
        raid5_conf_t *conf = sh->raid_conf;
        int disks = sh->disks, i;
-       unsigned long flags;
        int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags);
 
        if (bi->bi_size)
@@ -654,7 +653,6 @@ static int raid5_end_write_request (struct bio *bi, unsigned int bytes_done,
                return 0;
        }
 
-       spin_lock_irqsave(&conf->device_lock, flags);
        if (!uptodate)
                md_error(conf->mddev, conf->disks[i].rdev);
 
@@ -662,8 +660,7 @@ static int raid5_end_write_request (struct bio *bi, unsigned int bytes_done,
        
        clear_bit(R5_LOCKED, &sh->dev[i].flags);
        set_bit(STRIPE_HANDLE, &sh->state);
-       __release_stripe(conf, sh);
-       spin_unlock_irqrestore(&conf->device_lock, flags);
+       release_stripe(sh);
        return 0;
 }
 
@@ -696,12 +693,12 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
        PRINTK("raid5: error called\n");
 
        if (!test_bit(Faulty, &rdev->flags)) {
-               mddev->sb_dirty = 1;
-               if (test_bit(In_sync, &rdev->flags)) {
-                       conf->working_disks--;
+               set_bit(MD_CHANGE_DEVS, &mddev->flags);
+               if (test_and_clear_bit(In_sync, &rdev->flags)) {
+                       unsigned long flags;
+                       spin_lock_irqsave(&conf->device_lock, flags);
                        mddev->degraded++;
-                       conf->failed_disks++;
-                       clear_bit(In_sync, &rdev->flags);
+                       spin_unlock_irqrestore(&conf->device_lock, flags);
                        /*
                         * if recovery was running, make sure it aborts.
                         */
@@ -711,7 +708,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
                printk (KERN_ALERT
                        "raid5: Disk failure on %s, disabling device."
                        " Operation continuing on %d devices\n",
-                       bdevname(rdev->bdev,b), conf->working_disks);
+                       bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded);
        }
 }
 
@@ -1108,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;
@@ -1353,10 +1350,9 @@ static int page_is_zero(struct page *p)
 static int stripe_to_pdidx(sector_t stripe, raid5_conf_t *conf, int disks)
 {
        int sectors_per_chunk = conf->chunk_size >> 9;
-       sector_t x = stripe;
        int pd_idx, dd_idx;
-       int chunk_offset = sector_div(x, sectors_per_chunk);
-       stripe = x;
+       int chunk_offset = sector_div(stripe, sectors_per_chunk);
+
        raid5_compute_sector(stripe*(disks-1)*sectors_per_chunk
                             + chunk_offset, disks, disks-1, &dd_idx, &pd_idx, conf);
        return pd_idx;
@@ -2597,6 +2593,24 @@ static int raid5_issue_flush(request_queue_t *q, struct gendisk *disk,
        return ret;
 }
 
+static int raid5_congested(void *data, int bits)
+{
+       mddev_t *mddev = data;
+       raid5_conf_t *conf = mddev_to_conf(mddev);
+
+       /* No difference between reads and writes.  Just check
+        * how busy the stripe_cache is
+        */
+       if (conf->inactive_blocked)
+               return 1;
+       if (conf->quiesce)
+               return 1;
+       if (list_empty_careful(&conf->inactive_list))
+               return 1;
+
+       return 0;
+}
+
 static int make_request(request_queue_t *q, struct bio * bi)
 {
        mddev_t *mddev = q->queuedata;
@@ -2781,9 +2795,9 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
                wait_event(conf->wait_for_overlap,
                           atomic_read(&conf->reshape_stripes)==0);
                mddev->reshape_position = conf->expand_progress;
-               mddev->sb_dirty = 1;
+               set_bit(MD_CHANGE_DEVS, &mddev->flags);
                md_wakeup_thread(mddev->thread);
-               wait_event(mddev->sb_wait, mddev->sb_dirty == 0 ||
+               wait_event(mddev->sb_wait, mddev->flags == 0 ||
                           kthread_should_stop());
                spin_lock_irq(&conf->device_lock);
                conf->expand_lo = mddev->reshape_position;
@@ -3074,6 +3088,7 @@ static int run(mddev_t *mddev)
        mdk_rdev_t *rdev;
        struct disk_info *disk;
        struct list_head *tmp;
+       int working_disks = 0;
 
        if (mddev->level != 5 && mddev->level != 4 && mddev->level != 6) {
                printk(KERN_ERR "raid5: %s: raid level not set to 4/5/6 (%d)\n",
@@ -3176,14 +3191,14 @@ static int run(mddev_t *mddev)
                        printk(KERN_INFO "raid5: device %s operational as raid"
                                " disk %d\n", bdevname(rdev->bdev,b),
                                raid_disk);
-                       conf->working_disks++;
+                       working_disks++;
                }
        }
 
        /*
         * 0 for a fully functional array, 1 or 2 for a degraded array.
         */
-       mddev->degraded = conf->failed_disks = conf->raid_disks - conf->working_disks;
+       mddev->degraded = conf->raid_disks - working_disks;
        conf->mddev = mddev;
        conf->chunk_size = mddev->chunk_size;
        conf->level = mddev->level;
@@ -3218,7 +3233,7 @@ static int run(mddev_t *mddev)
        if (mddev->degraded > conf->max_degraded) {
                printk(KERN_ERR "raid5: not enough operational devices for %s"
                        " (%d/%d failed)\n",
-                       mdname(mddev), conf->failed_disks, conf->raid_disks);
+                       mdname(mddev), mddev->degraded, conf->raid_disks);
                goto abort;
        }
 
@@ -3299,6 +3314,9 @@ static int run(mddev_t *mddev)
 
        mddev->queue->unplug_fn = raid5_unplug_device;
        mddev->queue->issue_flush_fn = raid5_issue_flush;
+       mddev->queue->backing_dev_info.congested_fn = raid5_congested;
+       mddev->queue->backing_dev_info.congested_data = mddev;
+
        mddev->array_size =  mddev->size * (conf->previous_raid_disks -
                                            conf->max_degraded);
 
@@ -3375,7 +3393,7 @@ static void status (struct seq_file *seq, mddev_t *mddev)
        int i;
 
        seq_printf (seq, " level %d, %dk chunk, algorithm %d", mddev->level, mddev->chunk_size >> 10, mddev->layout);
-       seq_printf (seq, " [%d/%d] [", conf->raid_disks, conf->working_disks);
+       seq_printf (seq, " [%d/%d] [", conf->raid_disks, conf->raid_disks - mddev->degraded);
        for (i = 0; i < conf->raid_disks; i++)
                seq_printf (seq, "%s",
                               conf->disks[i].rdev &&
@@ -3397,8 +3415,8 @@ static void print_raid5_conf (raid5_conf_t *conf)
                printk("(conf==NULL)\n");
                return;
        }
-       printk(" --- rd:%d wd:%d fd:%d\n", conf->raid_disks,
-                conf->working_disks, conf->failed_disks);
+       printk(" --- rd:%d wd:%d\n", conf->raid_disks,
+                conf->raid_disks - conf->mddev->degraded);
 
        for (i = 0; i < conf->raid_disks; i++) {
                char b[BDEVNAME_SIZE];
@@ -3420,11 +3438,11 @@ static int raid5_spare_active(mddev_t *mddev)
                tmp = conf->disks + i;
                if (tmp->rdev
                    && !test_bit(Faulty, &tmp->rdev->flags)
-                   && !test_bit(In_sync, &tmp->rdev->flags)) {
+                   && !test_and_set_bit(In_sync, &tmp->rdev->flags)) {
+                       unsigned long flags;
+                       spin_lock_irqsave(&conf->device_lock, flags);
                        mddev->degraded--;
-                       conf->failed_disks--;
-                       conf->working_disks++;
-                       set_bit(In_sync, &tmp->rdev->flags);
+                       spin_unlock_irqrestore(&conf->device_lock, flags);
                }
        }
        print_raid5_conf(conf);
@@ -3560,6 +3578,7 @@ static int raid5_start_reshape(mddev_t *mddev)
        struct list_head *rtmp;
        int spares = 0;
        int added_devices = 0;
+       unsigned long flags;
 
        if (mddev->degraded ||
            test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
@@ -3593,7 +3612,6 @@ static int raid5_start_reshape(mddev_t *mddev)
                        if (raid5_add_disk(mddev, rdev)) {
                                char nm[20];
                                set_bit(In_sync, &rdev->flags);
-                               conf->working_disks++;
                                added_devices++;
                                rdev->recovery_offset = 0;
                                sprintf(nm, "rd%d", rdev->raid_disk);
@@ -3602,10 +3620,12 @@ static int raid5_start_reshape(mddev_t *mddev)
                                break;
                }
 
+       spin_lock_irqsave(&conf->device_lock, flags);
        mddev->degraded = (conf->raid_disks - conf->previous_raid_disks) - added_devices;
+       spin_unlock_irqrestore(&conf->device_lock, flags);
        mddev->raid_disks = conf->raid_disks;
        mddev->reshape_position = 0;
-       mddev->sb_dirty = 1;
+       set_bit(MD_CHANGE_DEVS, &mddev->flags);
 
        clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
        clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
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 3dd5dbafb330634c400e57d58b198eb21ef5c9a0..53304e6991ac61326fbec9001d362530f62bd8d9 100644 (file)
@@ -1014,6 +1014,13 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
        if ((ret = dvb_generic_open (inode, file)) < 0)
                return ret;
 
+       if (fe->ops.ts_bus_ctrl) {
+               if ((ret = fe->ops.ts_bus_ctrl (fe, 1)) < 0) {
+                       dvb_generic_release (inode, file);
+                       return ret;
+               }
+       }
+
        if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
 
                /* normal tune mode when opened R/W */
@@ -1043,6 +1050,9 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
        if ((file->f_flags & O_ACCMODE) != O_RDONLY)
                fepriv->release_jiffies = jiffies;
 
+       if (fe->ops.ts_bus_ctrl)
+               fe->ops.ts_bus_ctrl (fe, 0);
+
        return dvb_generic_release (inode, file);
 }
 
index e5d5028b3694fc68663da122664e6172095c596f..f233d78bc3644bfdd93670ac7447bb280e852e94 100644 (file)
@@ -129,6 +129,7 @@ struct dvb_frontend_ops {
        int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, long arg);
        int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd);
        int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable);
+       int (*ts_bus_ctrl)(struct dvb_frontend* fe, int acquire);
 
        struct dvb_tuner_ops tuner_ops;
 };
index c972fe014c58283bdbca41f584cb76be583b0b61..9878183ba3f0d8cc751cfbd968b3c7c9aa5d5d3b 100644 (file)
@@ -26,7 +26,6 @@
 
 
 
-#define __KERNEL_SYSCALLS__
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
index 0a3c35399bea7480ef9bdcc84bc510e43704ade2..67cefdd2334a5d31ec486f9e1cf996b70acc0852 100644 (file)
@@ -39,20 +39,8 @@ config DVB_USB_DIBUSB_MB
          Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by
          DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator.
 
-         Devices supported by this driver:
-           Artec T1 USB1.1 boxes
-           Avermedia AverTV DVBT USB1.1
-           Compro Videomate DVB-U2000 - DVB-T USB
-           DiBcom USB1.1 reference devices (non-public)
-           Grandtec DVB-T USB
-           Hama DVB-T USB1.1-Box
-           KWorld/JetWay/ADSTech V-Stream XPERT DTV - DVB-T USB1.1 and USB2.0
-           TwinhanDTV Magic Box (VP7041e)
-           TwinhanDTV USB-Ter (VP7041)
-           Ultima Electronic/Artec T1 USB TVBOX
-
-         The VP7041 seems to be identical to "CTS Portable" (Chinese
-         Television System).
+         For an up-to-date list of devices supported by this driver, have a look
+         on the Linux-DVB Wiki at www.linuxtv.org.
 
          Say Y if you own such a device and want to use it. You should build it as
          a module.
@@ -69,12 +57,29 @@ config DVB_USB_DIBUSB_MC
        select DVB_DIB3000MC
        select DVB_TUNER_MT2060
        help
-         Support for 2.0 DVB-T receivers based on reference designs made by
+         Support for USB2.0 DVB-T receivers based on reference designs made by
          DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator.
 
-         Devices supported by this driver:
-           Artec T1 USB2.0 boxes
-           DiBcom USB2.0 reference devices (non-public)
+         For an up-to-date list of devices supported by this driver, have a look
+         on the Linux-DVB Wiki at www.linuxtv.org.
+
+         Say Y if you own such a device and want to use it. You should build it as
+         a module.
+
+config DVB_USB_DIB0700
+       tristate "DiBcom DiB0700 USB DVB devices (see help for supported devices)"
+       depends on DVB_USB
+       select DVB_DIB7000M
+       select DVB_DIB3000MC
+       select DVB_TUNER_MT2060
+       help
+         Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The
+         USB bridge is also present in devices having the DiB7700 DVB-T-USB
+         silicon. This chip can be found in devices offered by Hauppauge,
+         Avermedia and other big and small companies.
+
+         For an up-to-date list of devices supported by this driver, have a look
+         on the Linux-DVB Wiki at www.linuxtv.org.
 
          Say Y if you own such a device and want to use it. You should build it as
          a module.
index 9643f56c7fe9a02e3f5e88e3d01bbd4875bf852a..e239107998e58d7b236ff90a3d75bdbf4b82fb44 100644 (file)
@@ -1,4 +1,4 @@
-dvb-usb-objs = dvb-usb-firmware.o dvb-usb-init.o dvb-usb-urb.o dvb-usb-i2c.o dvb-usb-dvb.o dvb-usb-remote.o
+dvb-usb-objs = dvb-usb-firmware.o dvb-usb-init.o dvb-usb-urb.o dvb-usb-i2c.o dvb-usb-dvb.o dvb-usb-remote.o usb-urb.o
 obj-$(CONFIG_DVB_USB) += dvb-usb.o
 
 dvb-usb-vp7045-objs = vp7045.o vp7045-fe.o
@@ -36,4 +36,7 @@ obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o
 dvb-usb-cxusb-objs = cxusb.o
 obj-$(CONFIG_DVB_USB_CXUSB) += dvb-usb-cxusb.o
 
+dvb-usb-dib0700-objs = dib0700_core.o dib0700_devices.o
+obj-$(CONFIG_DVB_USB_DIB0700) += dvb-usb-dib0700.o
+
 EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
index df0c384bd4ca8a0d677afcd2507e04685d068648..2ed3eb62d787c49d8cde32491f6e27dbf53a6e14 100644 (file)
@@ -27,7 +27,8 @@ static int a800_power_ctrl(struct dvb_usb_device *d, int onoff)
 }
 
 /* assure to put cold to 0 for iManufacturer == 1 */
-static int a800_identify_state(struct usb_device *udev, struct dvb_usb_properties *props,struct dvb_usb_device_description **desc, int *cold)
+static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
+       struct dvb_usb_device_description **desc, int *cold)
 {
        *cold = udev->descriptor.iManufacturer != 1;
        return 0;
@@ -88,7 +89,7 @@ static int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 }
 
 /* USB Driver stuff */
-static struct dvb_usb_properties a800_properties;
+static struct dvb_usb_device_properties a800_properties;
 
 static int a800_probe(struct usb_interface *intf,
                const struct usb_device_id *id)
@@ -104,35 +105,27 @@ static struct usb_device_id a800_table [] = {
 };
 MODULE_DEVICE_TABLE (usb, a800_table);
 
-static struct dvb_usb_properties a800_properties = {
-       .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
-       .pid_filter_count = 32,
+static struct dvb_usb_device_properties a800_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
        .usb_ctrl = CYPRESS_FX2,
-
        .firmware = "dvb-usb-avertv-a800-02.fw",
 
-       .size_of_priv     = sizeof(struct dibusb_state),
-
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                       .pid_filter_count = 32,
        .streaming_ctrl   = dibusb2_0_streaming_ctrl,
        .pid_filter       = dibusb_pid_filter,
        .pid_filter_ctrl  = dibusb_pid_filter_ctrl,
-       .power_ctrl       = a800_power_ctrl,
+
        .frontend_attach  = dibusb_dib3000mc_frontend_attach,
        .tuner_attach     = dibusb_dib3000mc_tuner_attach,
-       .identify_state   = a800_identify_state,
-
-       .rc_interval      = DEFAULT_RC_INTERVAL,
-       .rc_key_map       = a800_rc_keys,
-       .rc_key_map_size  = ARRAY_SIZE(a800_rc_keys),
-       .rc_query         = a800_rc_query,
 
-       .i2c_algo         = &dibusb_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
        /* parameter for the MPEG2-data transfer */
-       .urb = {
-               .type = DVB_USB_BULK,
+                       .stream = {
+                               .type = USB_BULK,
                .count = 7,
                .endpoint = 0x06,
                .u = {
@@ -142,6 +135,21 @@ static struct dvb_usb_properties a800_properties = {
                }
        },
 
+                       .size_of_priv     = sizeof(struct dibusb_state),
+               },
+       },
+
+       .power_ctrl       = a800_power_ctrl,
+       .identify_state   = a800_identify_state,
+
+       .rc_interval      = DEFAULT_RC_INTERVAL,
+       .rc_key_map       = a800_rc_keys,
+       .rc_key_map_size  = ARRAY_SIZE(a800_rc_keys),
+       .rc_query         = a800_rc_query,
+
+       .i2c_algo         = &dibusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
        .num_device_descs = 1,
        .devices = {
                {   "AVerMedia AverTV DVB-T USB 2.0 (A800)",
index c710c0176e0737e9174d3529b88e3e5db69d3dc8..43f39069ef34551eadbf746ba3da2bf5e9291db3 100644 (file)
@@ -161,13 +161,13 @@ static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff)
                return 0;
 }
 
-static int cxusb_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 {
        u8 buf[2] = { 0x03, 0x00 };
        if (onoff)
-               cxusb_ctrl_msg(d,CMD_STREAMING_ON, buf, 2, NULL, 0);
+               cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON, buf, 2, NULL, 0);
        else
-               cxusb_ctrl_msg(d,CMD_STREAMING_OFF, NULL, 0, NULL, 0);
+               cxusb_ctrl_msg(adap->dev, CMD_STREAMING_OFF, NULL, 0, NULL, 0);
 
        return 0;
 }
@@ -327,8 +327,8 @@ static int cxusb_mt352_demod_init(struct dvb_frontend* fe)
 static int cxusb_lgh064f_tuner_set_params(struct dvb_frontend *fe,
                                          struct dvb_frontend_parameters *fep)
 {
-       struct dvb_usb_device *d = fe->dvb->priv;
-       return lg_h06xf_pll_set(fe, &d->i2c_adap, fep);
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+       return lg_h06xf_pll_set(fe, &adap->dev->i2c_adap, fep);
 }
 
 static struct cx22702_config cxusb_cx22702_config = {
@@ -359,98 +359,99 @@ static struct mt352_config cxusb_mt352_config = {
 };
 
 /* Callbacks for DVB USB */
-static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_device *d)
+static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
 {
        u8 bpll[4] = { 0x0b, 0xdc, 0x9c, 0xa0 };
-       d->pll_addr = 0x61;
-       memcpy(d->pll_init, bpll, 4);
-       d->pll_desc = &dvb_pll_fmd1216me;
+       adap->pll_addr = 0x61;
+       memcpy(adap->pll_init, bpll, 4);
+       adap->pll_desc = &dvb_pll_fmd1216me;
 
-       d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c;
-       d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
+       adap->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c;
+       adap->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
 
        return 0;
 }
 
-static int cxusb_dee1601_tuner_attach(struct dvb_usb_device *d)
+static int cxusb_dee1601_tuner_attach(struct dvb_usb_adapter *adap)
 {
-       d->pll_addr = 0x61;
-       d->pll_desc = &dvb_pll_thomson_dtt7579;
-       d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
+       adap->pll_addr = 0x61;
+       adap->pll_desc = &dvb_pll_thomson_dtt7579;
+       adap->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
        return 0;
 }
 
-static int cxusb_lgz201_tuner_attach(struct dvb_usb_device *d)
+static int cxusb_lgz201_tuner_attach(struct dvb_usb_adapter *adap)
 {
-       d->pll_addr = 0x61;
-       d->pll_desc = &dvb_pll_lg_z201;
-       d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
+       adap->pll_addr = 0x61;
+       adap->pll_desc = &dvb_pll_lg_z201;
+       adap->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
        return 0;
 }
 
-static int cxusb_dtt7579_tuner_attach(struct dvb_usb_device *d)
+static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap)
 {
-       d->pll_addr = 0x60;
-       d->pll_desc = &dvb_pll_thomson_dtt7579;
-       d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
+       adap->pll_addr = 0x60;
+       adap->pll_desc = &dvb_pll_thomson_dtt7579;
+       adap->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
        return 0;
 }
 
-static int cxusb_lgdt3303_tuner_attach(struct dvb_usb_device *d)
+static int cxusb_lgdt3303_tuner_attach(struct dvb_usb_adapter *adap)
 {
-       d->fe->ops.tuner_ops.set_params = cxusb_lgh064f_tuner_set_params;
+       adap->fe->ops.tuner_ops.set_params = cxusb_lgh064f_tuner_set_params;
        return 0;
 }
 
-static int cxusb_cx22702_frontend_attach(struct dvb_usb_device *d)
+static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap)
 {
        u8 b;
-       if (usb_set_interface(d->udev,0,6) < 0)
+       if (usb_set_interface(adap->dev->udev, 0, 6) < 0)
                err("set interface failed");
 
-       cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, &b, 1);
+       cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, &b, 1);
 
-       if ((d->fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config, &d->i2c_adap)) != NULL)
+       if ((adap->fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config, &adap->dev->i2c_adap)) != NULL)
                return 0;
 
        return -EIO;
 }
 
-static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_device *d)
+static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
 {
-       if (usb_set_interface(d->udev,0,7) < 0)
+       if (usb_set_interface(adap->dev->udev, 0, 7) < 0)
                err("set interface failed");
 
-       cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0);
+       cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
 
-       if ((d->fe = dvb_attach(lgdt330x_attach, &cxusb_lgdt3303_config, &d->i2c_adap)) != NULL)
+       if ((adap->fe = dvb_attach(lgdt330x_attach, &cxusb_lgdt3303_config, &adap->dev->i2c_adap)) != NULL)
                return 0;
 
        return -EIO;
 }
 
-static int cxusb_mt352_frontend_attach(struct dvb_usb_device *d)
-{      /* used in both lgz201 and th7579 */
-       if (usb_set_interface(d->udev,0,0) < 0)
+static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       /* used in both lgz201 and th7579 */
+       if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
                err("set interface failed");
 
-       cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0);
+       cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
 
-       if ((d->fe = dvb_attach(mt352_attach, &cxusb_mt352_config, &d->i2c_adap)) != NULL)
+       if ((adap->fe = dvb_attach(mt352_attach, &cxusb_mt352_config, &adap->dev->i2c_adap)) != NULL)
                return 0;
 
        return -EIO;
 }
 
-static int cxusb_dee1601_frontend_attach(struct dvb_usb_device *d)
+static int cxusb_dee1601_frontend_attach(struct dvb_usb_adapter *adap)
 {
-       if (usb_set_interface(d->udev,0,0) < 0)
+       if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
                err("set interface failed");
 
-       cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0);
+       cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
 
-       if (((d->fe = dvb_attach(mt352_attach, &cxusb_dee1601_config, &d->i2c_adap)) != NULL) ||
-               ((d->fe = dvb_attach(zl10353_attach, &cxusb_zl10353_dee1601_config, &d->i2c_adap)) != NULL))
+       if (((adap->fe = dvb_attach(mt352_attach, &cxusb_dee1601_config, &adap->dev->i2c_adap)) != NULL) ||
+               ((adap->fe = dvb_attach(zl10353_attach, &cxusb_zl10353_dee1601_config, &adap->dev->i2c_adap)) != NULL))
                return 0;
 
        return -EIO;
@@ -480,11 +481,11 @@ static int bluebird_patch_dvico_firmware_download(struct usb_device *udev, const
 }
 
 /* DVB USB Driver stuff */
-static struct dvb_usb_properties cxusb_medion_properties;
-static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties;
-static struct dvb_usb_properties cxusb_bluebird_dee1601_properties;
-static struct dvb_usb_properties cxusb_bluebird_lgz201_properties;
-static struct dvb_usb_properties cxusb_bluebird_dtt7579_properties;
+static struct dvb_usb_device_properties cxusb_medion_properties;
+static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties;
+static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties;
+static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties;
+static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties;
 
 static int cxusb_probe(struct usb_interface *intf,
                const struct usb_device_id *id)
@@ -504,36 +505,36 @@ static struct usb_device_id cxusb_table [] = {
                { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
                { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) },
                { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) },
-               { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DEE1601_COLD) },
-               { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DEE1601_WARM) },
+               { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD) },
+               { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM) },
                { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_COLD) },
                { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_WARM) },
                { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_COLD) },
                { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_WARM) },
-               { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DEE1601_COLD) },
-               { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DEE1601_WARM) },
+               { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD) },
+               { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM) },
+               { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD) },
+               { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM) },
                {}              /* Terminating entry */
 };
 MODULE_DEVICE_TABLE (usb, cxusb_table);
 
-static struct dvb_usb_properties cxusb_medion_properties = {
+static struct dvb_usb_device_properties cxusb_medion_properties = {
        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
        .usb_ctrl = CYPRESS_FX2,
 
        .size_of_priv     = sizeof(struct cxusb_state),
 
+       .num_adapters = 1,
+       .adapter = {
+               {
        .streaming_ctrl   = cxusb_streaming_ctrl,
-       .power_ctrl       = cxusb_power_ctrl,
        .frontend_attach  = cxusb_cx22702_frontend_attach,
        .tuner_attach     = cxusb_fmd1216me_tuner_attach,
-
-       .i2c_algo         = &cxusb_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
        /* parameter for the MPEG2-data transfer */
-       .urb = {
-               .type = DVB_USB_BULK,
+                       .stream = {
+                               .type = USB_BULK,
                .count = 5,
                .endpoint = 0x02,
                .u = {
@@ -543,6 +544,14 @@ static struct dvb_usb_properties cxusb_medion_properties = {
                }
        },
 
+               },
+       },
+       .power_ctrl       = cxusb_power_ctrl,
+
+       .i2c_algo         = &cxusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
        .num_device_descs = 1,
        .devices = {
                {   "Medion MD95700 (MDUSBTV-HYBRID)",
@@ -552,7 +561,7 @@ static struct dvb_usb_properties cxusb_medion_properties = {
        }
 };
 
-static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties = {
+static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = {
        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
        .usb_ctrl          = DEVICE_SPECIFIC,
@@ -563,22 +572,16 @@ static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties = {
 
        .size_of_priv     = sizeof(struct cxusb_state),
 
+       .num_adapters = 1,
+       .adapter = {
+               {
        .streaming_ctrl   = cxusb_streaming_ctrl,
-       .power_ctrl       = cxusb_bluebird_power_ctrl,
        .frontend_attach  = cxusb_lgdt3303_frontend_attach,
        .tuner_attach     = cxusb_lgdt3303_tuner_attach,
 
-       .i2c_algo         = &cxusb_i2c_algo,
-
-       .rc_interval      = 100,
-       .rc_key_map       = dvico_portable_rc_keys,
-       .rc_key_map_size  = ARRAY_SIZE(dvico_portable_rc_keys),
-       .rc_query         = cxusb_rc_query,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
        /* parameter for the MPEG2-data transfer */
-       .urb = {
-               .type = DVB_USB_BULK,
+                       .stream = {
+                               .type = USB_BULK,
                .count = 5,
                .endpoint = 0x02,
                .u = {
@@ -587,6 +590,19 @@ static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties = {
                        }
                }
        },
+               },
+       },
+
+       .power_ctrl       = cxusb_bluebird_power_ctrl,
+
+       .i2c_algo         = &cxusb_i2c_algo,
+
+       .rc_interval      = 100,
+       .rc_key_map       = dvico_portable_rc_keys,
+       .rc_key_map_size  = ARRAY_SIZE(dvico_portable_rc_keys),
+       .rc_query         = cxusb_rc_query,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
 
        .num_device_descs = 1,
        .devices = {
@@ -597,7 +613,7 @@ static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties = {
        }
 };
 
-static struct dvb_usb_properties cxusb_bluebird_dee1601_properties = {
+static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = {
        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
        .usb_ctrl          = DEVICE_SPECIFIC,
@@ -608,22 +624,15 @@ static struct dvb_usb_properties cxusb_bluebird_dee1601_properties = {
 
        .size_of_priv     = sizeof(struct cxusb_state),
 
+       .num_adapters = 1,
+       .adapter = {
+               {
        .streaming_ctrl   = cxusb_streaming_ctrl,
-       .power_ctrl       = cxusb_bluebird_power_ctrl,
        .frontend_attach  = cxusb_dee1601_frontend_attach,
        .tuner_attach     = cxusb_dee1601_tuner_attach,
-
-       .i2c_algo         = &cxusb_i2c_algo,
-
-       .rc_interval      = 150,
-       .rc_key_map       = dvico_mce_rc_keys,
-       .rc_key_map_size  = ARRAY_SIZE(dvico_mce_rc_keys),
-       .rc_query         = cxusb_rc_query,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
        /* parameter for the MPEG2-data transfer */
-       .urb = {
-               .type = DVB_USB_BULK,
+                       .stream = {
+                               .type = USB_BULK,
                .count = 5,
                .endpoint = 0x04,
                .u = {
@@ -632,8 +641,21 @@ static struct dvb_usb_properties cxusb_bluebird_dee1601_properties = {
                        }
                }
        },
+               },
+       },
+
+       .power_ctrl       = cxusb_bluebird_power_ctrl,
 
-       .num_device_descs = 2,
+       .i2c_algo         = &cxusb_i2c_algo,
+
+       .rc_interval      = 150,
+       .rc_key_map       = dvico_mce_rc_keys,
+       .rc_key_map_size  = ARRAY_SIZE(dvico_mce_rc_keys),
+       .rc_query         = cxusb_rc_query,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .num_device_descs = 3,
        .devices = {
                {   "DViCO FusionHDTV DVB-T Dual USB",
                        { &cxusb_table[3], NULL },
@@ -643,10 +665,14 @@ static struct dvb_usb_properties cxusb_bluebird_dee1601_properties = {
                        { &cxusb_table[9],  NULL },
                        { &cxusb_table[10], NULL },
                },
+               {   "DViCO FusionHDTV DVB-T Dual Digital 2",
+                       { &cxusb_table[11], NULL },
+                       { &cxusb_table[12], NULL },
+               },
        }
 };
 
-static struct dvb_usb_properties cxusb_bluebird_lgz201_properties = {
+static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = {
        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
        .usb_ctrl          = DEVICE_SPECIFIC,
@@ -657,22 +683,16 @@ static struct dvb_usb_properties cxusb_bluebird_lgz201_properties = {
 
        .size_of_priv     = sizeof(struct cxusb_state),
 
+       .num_adapters = 2,
+       .adapter = {
+               {
        .streaming_ctrl   = cxusb_streaming_ctrl,
-       .power_ctrl       = cxusb_bluebird_power_ctrl,
        .frontend_attach  = cxusb_mt352_frontend_attach,
        .tuner_attach     = cxusb_lgz201_tuner_attach,
 
-       .i2c_algo         = &cxusb_i2c_algo,
-
-       .rc_interval      = 100,
-       .rc_key_map       = dvico_portable_rc_keys,
-       .rc_key_map_size  = ARRAY_SIZE(dvico_portable_rc_keys),
-       .rc_query         = cxusb_rc_query,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
        /* parameter for the MPEG2-data transfer */
-       .urb = {
-               .type = DVB_USB_BULK,
+                       .stream = {
+                               .type = USB_BULK,
                .count = 5,
                .endpoint = 0x04,
                .u = {
@@ -681,7 +701,18 @@ static struct dvb_usb_properties cxusb_bluebird_lgz201_properties = {
                        }
                }
        },
+               },
+       },
+       .power_ctrl       = cxusb_bluebird_power_ctrl,
+
+       .i2c_algo         = &cxusb_i2c_algo,
 
+       .rc_interval      = 100,
+       .rc_key_map       = dvico_portable_rc_keys,
+       .rc_key_map_size  = ARRAY_SIZE(dvico_portable_rc_keys),
+       .rc_query         = cxusb_rc_query,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
        .num_device_descs = 1,
        .devices = {
                {   "DViCO FusionHDTV DVB-T USB (LGZ201)",
@@ -691,7 +722,7 @@ static struct dvb_usb_properties cxusb_bluebird_lgz201_properties = {
        }
 };
 
-static struct dvb_usb_properties cxusb_bluebird_dtt7579_properties = {
+static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = {
        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
        .usb_ctrl          = DEVICE_SPECIFIC,
@@ -702,22 +733,16 @@ static struct dvb_usb_properties cxusb_bluebird_dtt7579_properties = {
 
        .size_of_priv     = sizeof(struct cxusb_state),
 
+       .num_adapters = 1,
+       .adapter = {
+               {
        .streaming_ctrl   = cxusb_streaming_ctrl,
-       .power_ctrl       = cxusb_bluebird_power_ctrl,
        .frontend_attach  = cxusb_mt352_frontend_attach,
        .tuner_attach     = cxusb_dtt7579_tuner_attach,
 
-       .i2c_algo         = &cxusb_i2c_algo,
-
-       .rc_interval      = 100,
-       .rc_key_map       = dvico_portable_rc_keys,
-       .rc_key_map_size  = ARRAY_SIZE(dvico_portable_rc_keys),
-       .rc_query         = cxusb_rc_query,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
        /* parameter for the MPEG2-data transfer */
-       .urb = {
-               .type = DVB_USB_BULK,
+                       .stream = {
+                               .type = USB_BULK,
                .count = 5,
                .endpoint = 0x04,
                .u = {
@@ -726,6 +751,18 @@ static struct dvb_usb_properties cxusb_bluebird_dtt7579_properties = {
                        }
                }
        },
+               },
+       },
+       .power_ctrl       = cxusb_bluebird_power_ctrl,
+
+       .i2c_algo         = &cxusb_i2c_algo,
+
+       .rc_interval      = 100,
+       .rc_key_map       = dvico_portable_rc_keys,
+       .rc_key_map_size  = ARRAY_SIZE(dvico_portable_rc_keys),
+       .rc_query         = cxusb_rc_query,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
 
        .num_device_descs = 1,
        .devices = {
diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h
new file mode 100644 (file)
index 0000000..ac84347
--- /dev/null
@@ -0,0 +1,49 @@
+/* Linux driver for devices based on the DiBcom DiB0700 USB bridge
+ *
+ *     This program is free software; you can redistribute it and/or modify it
+ *     under the terms of the GNU General Public License as published by the Free
+ *     Software Foundation, version 2.
+ *
+ *  Copyright (C) 2005-6 DiBcom, SA
+ */
+#ifndef _DIB0700_H_
+#define _DIB0700_H_
+
+#define DVB_USB_LOG_PREFIX "dib0700"
+#include "dvb-usb.h"
+
+#include "dib07x0.h"
+
+extern int dvb_usb_dib0700_debug;
+#define deb_info(args...)   dprintk(dvb_usb_dib0700_debug,0x01,args)
+#define deb_fw(args...)     dprintk(dvb_usb_dib0700_debug,0x02,args)
+#define deb_fwdata(args...) dprintk(dvb_usb_dib0700_debug,0x04,args)
+#define deb_data(args...)   dprintk(dvb_usb_dib0700_debug,0x08,args)
+
+#define REQUEST_I2C_READ     0x2
+#define REQUEST_I2C_WRITE    0x3
+#define REQUEST_POLL_RC      0x4
+#define REQUEST_JUMPRAM      0x8
+#define REQUEST_SET_GPIO     0xC
+#define REQUEST_ENABLE_VIDEO 0xF
+       // 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog)
+       // 2 Byte: MPEG2 mode:  4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1)
+       // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines)    4LSB(     "                "           )
+
+struct dib0700_state {
+       u8 channel_state;
+       u16 mt2060_if1[2];
+};
+
+extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val);
+extern int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw);
+extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff);
+extern struct i2c_algorithm dib0700_i2c_algo;
+extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
+                       struct dvb_usb_device_description **desc, int *cold);
+
+extern int dib0700_device_count;
+extern struct dvb_usb_device_properties dib0700_devices[];
+extern struct usb_device_id dib0700_usb_id_table[];
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
new file mode 100644 (file)
index 0000000..dca6c69
--- /dev/null
@@ -0,0 +1,279 @@
+/* Linux driver for devices based on the DiBcom DiB0700 USB bridge
+ *
+ *     This program is free software; you can redistribute it and/or modify it
+ *     under the terms of the GNU General Public License as published by the Free
+ *     Software Foundation, version 2.
+ *
+ *  Copyright (C) 2005-6 DiBcom, SA
+ */
+#include "dib0700.h"
+
+/* debug */
+int dvb_usb_dib0700_debug;
+module_param_named(debug,dvb_usb_dib0700_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,2=fw,4=fwdata,8=data (or-able))." DVB_USB_DEBUG_STATUS);
+
+/* expecting rx buffer: request data[0] data[1] ... data[2] */
+static int dib0700_ctrl_wr(struct dvb_usb_device *d, u8 *tx, u8 txlen)
+{
+       int status;
+
+       deb_data(">>> ");
+       debug_dump(tx,txlen,deb_data);
+
+       status = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev,0),
+               tx[0], USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0, tx, txlen,
+               USB_CTRL_GET_TIMEOUT);
+
+       if (status != txlen)
+               deb_data("ep 0 write error (status = %d, len: %d)\n",status,txlen);
+
+       return status < 0 ? status : 0;
+}
+
+/* expecting tx buffer: request data[0] ... data[n] (n <= 4) */
+static int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen)
+{
+       u16 index, value;
+       int status;
+
+       if (txlen < 2) {
+               err("tx buffer length is smaller than 2. Makes no sense.");
+               return -EINVAL;
+       }
+       if (txlen > 4) {
+               err("tx buffer length is larger than 4. Not supported.");
+               return -EINVAL;
+       }
+
+       deb_data(">>> ");
+       debug_dump(tx,txlen,deb_data);
+
+       value = ((txlen - 2) << 8) | tx[1];
+       index = 0;
+       if (txlen > 2)
+               index |= (tx[2] << 8);
+       if (txlen > 3)
+               index |= tx[3];
+
+       /* think about swapping here */
+       value = le16_to_cpu(value);
+       index = le16_to_cpu(index);
+
+       status = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev,0), tx[0],
+                       USB_TYPE_VENDOR | USB_DIR_IN, value, index, rx, rxlen,
+                       USB_CTRL_GET_TIMEOUT);
+
+       if (status < 0)
+               deb_info("ep 0 read error (status = %d)\n",status);
+
+       deb_data("<<< ");
+       debug_dump(rx,rxlen,deb_data);
+
+       return status; /* length in case of success */
+}
+
+int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val)
+{
+       u8 buf[3] = { REQUEST_SET_GPIO, gpio, ((gpio_dir & 0x01) << 7) | ((gpio_val & 0x01) << 6) };
+       return dib0700_ctrl_wr(d,buf,3);
+}
+
+/*
+ * I2C master xfer function
+ */
+static int dib0700_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg *msg,int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       int i,len;
+       u8 buf[255];
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       for (i = 0; i < num; i++) {
+               /* fill in the address */
+               buf[1] = (msg[i].addr << 1);
+               /* fill the buffer */
+               memcpy(&buf[2], msg[i].buf, msg[i].len);
+
+               /* write/read request */
+               if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
+                       buf[0] = REQUEST_I2C_READ;
+                       buf[1] |= 1;
+
+                       /* special thing in the current firmware: when length is zero the read-failed */
+                       if ((len = dib0700_ctrl_rd(d, buf, msg[i].len + 2, msg[i+1].buf, msg[i+1].len)) <= 0) {
+                               deb_info("I2C read failed on address %x\n", msg[i].addr);
+                               break;
+                       }
+
+                       msg[i+1].len = len;
+
+                       i++;
+               } else {
+                       buf[0] = REQUEST_I2C_WRITE;
+                       if (dib0700_ctrl_wr(d, buf, msg[i].len + 2) < 0)
+                               break;
+               }
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+       return i;
+}
+
+static u32 dib0700_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+struct i2c_algorithm dib0700_i2c_algo = {
+       .master_xfer   = dib0700_i2c_xfer,
+       .functionality = dib0700_i2c_func,
+};
+
+int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
+                       struct dvb_usb_device_description **desc, int *cold)
+{
+       u8 buf[3] = { REQUEST_SET_GPIO, 4, (GPIO_IN << 7) | (0 << 6) }; // GPIO4 is save - used for I2C
+       *cold = usb_control_msg(udev, usb_sndctrlpipe(udev,0),
+               buf[0], USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0, buf, 3, USB_CTRL_GET_TIMEOUT) != 3;
+
+       deb_info("cold: %d\n", *cold);
+       return 0;
+}
+
+static int dib0700_jumpram(struct usb_device *udev, u32 address)
+{
+       int ret, actlen;
+       u8 buf[8] = { REQUEST_JUMPRAM, 0, 0, 0,
+               (address >> 24) & 0xff,
+               (address >> 16) & 0xff,
+               (address >> 8)  & 0xff,
+                address        & 0xff };
+
+       if ((ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x01),buf,8,&actlen,1000)) < 0) {
+               deb_fw("jumpram to 0x%x failed\n",address);
+               return ret;
+       }
+       if (actlen != 8) {
+               deb_fw("jumpram to 0x%x failed\n",address);
+               return -EIO;
+       }
+       return 0;
+}
+
+int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw)
+{
+       struct hexline hx;
+       int pos = 0, ret, act_len;
+
+       u8 buf[260];
+
+       while ((ret = dvb_usb_get_hexline(fw, &hx, &pos)) > 0) {
+               deb_fwdata("writing to address 0x%08x (buffer: 0x%02x %02x)\n",hx.addr, hx.len, hx.chk);
+
+               buf[0] = hx.len;
+               buf[1] = (hx.addr >> 8) & 0xff;
+               buf[2] =  hx.addr       & 0xff;
+               buf[3] = hx.type;
+               memcpy(&buf[4],hx.data,hx.len);
+               buf[4+hx.len] = hx.chk;
+
+               ret = usb_bulk_msg(udev,
+                       usb_sndbulkpipe(udev, 0x01),
+                       buf,
+                       hx.len + 5,
+                       &act_len,
+                       1000);
+
+               if (ret < 0) {
+                       err("firmware download failed at %d with %d",pos,ret);
+                       return ret;
+               }
+       }
+
+       if (ret == 0) {
+               /* start the firmware */
+               if ((ret = dib0700_jumpram(udev, 0x70000000)) == 0) {
+                       info("firmware started successfully.");
+                       msleep(100);
+               }
+       } else
+               ret = -EIO;
+
+       return ret;
+}
+
+int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+       struct dib0700_state *st = adap->dev->priv;
+       u8 b[4];
+
+       b[0] = REQUEST_ENABLE_VIDEO;
+       b[1] = 0x00;
+       b[2] = (0x01 << 4); /* Master mode */
+       b[3] = 0x00;
+
+       deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id);
+
+       if (onoff)
+               st->channel_state |=   1 << adap->id;
+       else
+               st->channel_state &= ~(1 << adap->id);
+
+       b[2] |= st->channel_state;
+
+       if (st->channel_state) /* if at least one channel is active */
+               b[1] = (0x01 << 4) | 0x00;
+
+       deb_info("data for streaming: %x %x\n",b[1],b[2]);
+
+       return dib0700_ctrl_wr(adap->dev, b, 4);
+}
+
+static int dib0700_probe(struct usb_interface *intf,
+               const struct usb_device_id *id)
+{
+       int i;
+
+       for (i = 0; i < dib0700_device_count; i++)
+               if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE, NULL) == 0)
+                       return 0;
+
+       return -ENODEV;
+}
+
+static struct usb_driver dib0700_driver = {
+       .name       = "dvb_usb_dib0700",
+       .probe      = dib0700_probe,
+       .disconnect = dvb_usb_device_exit,
+       .id_table   = dib0700_usb_id_table,
+};
+
+/* module stuff */
+static int __init dib0700_module_init(void)
+{
+       int result;
+       info("loaded with support for %d different device-types", dib0700_device_count);
+       if ((result = usb_register(&dib0700_driver))) {
+               err("usb_register failed. Error number %d",result);
+               return result;
+       }
+
+       return 0;
+}
+
+static void __exit dib0700_module_exit(void)
+{
+       /* deregister this driver from the USB subsystem */
+       usb_deregister(&dib0700_driver);
+}
+
+module_init (dib0700_module_init);
+module_exit (dib0700_module_exit);
+
+MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
+MODULE_DESCRIPTION("Driver for devices based on DiBcom DiB0700 - USB bridge");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
new file mode 100644 (file)
index 0000000..e473bfe
--- /dev/null
@@ -0,0 +1,212 @@
+/* Linux driver for devices based on the DiBcom DiB0700 USB bridge
+ *
+ *     This program is free software; you can redistribute it and/or modify it
+ *     under the terms of the GNU General Public License as published by the Free
+ *     Software Foundation, version 2.
+ *
+ *  Copyright (C) 2005-6 DiBcom, SA
+ */
+#include "dib0700.h"
+
+#include "dib3000mc.h"
+#include "mt2060.h"
+
+static int force_lna_activation;
+module_param(force_lna_activation, int, 0644);
+MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplifyer(s) (LNA), "
+               "if applicable for the device (default: 0=automatic/off).");
+
+/* Hauppauge Nova-T 500
+ *  has a LNA on GPIO0 which is enabled by setting 1 */
+static struct mt2060_config bristol_mt2060_config[2] = {
+       {
+               .i2c_address = 0x60,
+               .clock_out   = 3,
+       }, {
+               .i2c_address = 0x61,
+       }
+};
+
+static struct dibx000_agc_config bristol_dib3000p_mt2060_agc_config = {
+       .band_caps = BAND_VHF | BAND_UHF,
+       .setup     = (1 << 8) | (5 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (2 << 0),
+
+       .agc1_max = 42598,
+       .agc1_min = 17694,
+       .agc2_max = 45875,
+       .agc2_min = 0,
+
+       .agc1_pt1 = 0,
+       .agc1_pt2 = 59,
+
+       .agc1_slope1 = 0,
+       .agc1_slope2 = 69,
+
+       .agc2_pt1 = 0,
+       .agc2_pt2 = 59,
+
+       .agc2_slope1 = 111,
+       .agc2_slope2 = 28,
+};
+
+static struct dib3000mc_config bristol_dib3000mc_config[2] = {
+       {       .agc          = &bristol_dib3000p_mt2060_agc_config,
+               .max_time     = 0x196,
+               .ln_adc_level = 0x1cc7,
+               .output_mpeg2_in_188_bytes = 1,
+       },
+       {       .agc          = &bristol_dib3000p_mt2060_agc_config,
+               .max_time     = 0x196,
+               .ln_adc_level = 0x1cc7,
+               .output_mpeg2_in_188_bytes = 1,
+       }
+};
+
+static int bristol_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_state *st = adap->dev->priv;
+       if (adap->id == 0) {
+               dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 0); msleep(10);
+               dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 1); msleep(10);
+               dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
+               dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10);
+
+               if (force_lna_activation)
+                       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+               else
+                       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);
+
+               if (dib3000mc_i2c_enumeration(&adap->dev->i2c_adap, 2, DEFAULT_DIB3000P_I2C_ADDRESS, bristol_dib3000mc_config) != 0) {
+                       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(10);
+                       return -ENODEV;
+               }
+       }
+       st->mt2060_if1[adap->id] = 1220;
+       return (adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap,
+               (10 + adap->id) << 1, &bristol_dib3000mc_config[adap->id])) == NULL ? -ENODEV : 0;
+}
+
+static int bristol_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_state *st = adap->dev->priv;
+       struct i2c_adapter *tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe, 1);
+       return dvb_attach(mt2060_attach,adap->fe, tun_i2c, &bristol_mt2060_config[adap->id],
+               st->mt2060_if1[adap->id]) == NULL ? -ENODEV : 0;
+}
+
+/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
+/*
+static struct mt2060_config stk7000p_mt2060_config = {
+       0x60
+};
+*/
+
+static int stk7700p_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       /* unless there is no real power management in DVB - we leave the device on GPIO6 */
+       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
+
+//     adap->fe = dib7000m_attach(&adap->dev->i2c_adap, &stk7700p_dib7000m_config, 18);
+       return 0;
+}
+
+static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap)
+{
+//     tun_i2c = dib7000m_get_tuner_i2c_master(adap->fe, 1);
+//     return mt2060_attach(adap->fe, tun_i2c, &stk3000p_mt2060_config, if1);
+       return 0;
+}
+
+struct usb_device_id dib0700_usb_id_table[] = {
+               { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700P) },
+               { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500) },
+               { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_2) },
+               { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK) },
+               { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR) },
+               { }             /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
+
+#define DIB0700_DEFAULT_DEVICE_PROPERTIES \
+       .caps              = DVB_USB_IS_AN_I2C_ADAPTER, \
+       .usb_ctrl          = DEVICE_SPECIFIC, \
+       .firmware          = "dvb-usb-dib0700-01.fw", \
+       .download_firmware = dib0700_download_firmware, \
+       .no_reconnect      = 1, \
+       .size_of_priv      = sizeof(struct dib0700_state), \
+       .i2c_algo          = &dib0700_i2c_algo, \
+       .identify_state    = dib0700_identify_state
+
+#define DIB0700_DEFAULT_STREAMING_CONFIG(ep) \
+       .streaming_ctrl   = dib0700_streaming_ctrl, \
+       .stream = { \
+               .type = USB_BULK, \
+               .count = 4, \
+               .endpoint = ep, \
+               .u = { \
+                       .bulk = { \
+                               .buffersize = 39480, \
+                       } \
+               } \
+       }
+
+struct dvb_usb_device_properties dib0700_devices[] = {
+       {
+               DIB0700_DEFAULT_DEVICE_PROPERTIES,
+
+               .num_adapters = 1,
+               .adapter = {
+                       {
+                               .frontend_attach  = stk7700p_frontend_attach,
+                               .tuner_attach     = stk7700p_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                       },
+               },
+
+               .num_device_descs = 3,
+               .devices = {
+                       {   "DiBcom STK7700P reference design",
+                               { &dib0700_usb_id_table[0], NULL },
+                               { NULL },
+                       },
+                       {   "Hauppauge Nova-T Stick",
+                               { &dib0700_usb_id_table[3], NULL },
+                               { NULL },
+                       },
+                       {   "AVerMedia AVerTV DVB-T Volar",
+                               { &dib0700_usb_id_table[4], NULL },
+                               { NULL },
+                       },
+               }
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+
+               .num_adapters = 2,
+               .adapter = {
+                       {
+                               .frontend_attach  = bristol_frontend_attach,
+                               .tuner_attach     = bristol_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                       }, {
+                               .frontend_attach  = bristol_frontend_attach,
+                               .tuner_attach     = bristol_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
+                       }
+               },
+
+               .num_device_descs = 1,
+               .devices = {
+                       {   "Hauppauge Nova-T 500 Dual DVB-T",
+                               { &dib0700_usb_id_table[1], &dib0700_usb_id_table[2], NULL },
+                               { NULL },
+                       },
+               }
+       }
+};
+
+int dib0700_device_count = ARRAY_SIZE(dib0700_devices);
diff --git a/drivers/media/dvb/dvb-usb/dib07x0.h b/drivers/media/dvb/dvb-usb/dib07x0.h
new file mode 100644 (file)
index 0000000..7e62c10
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef _DIB07X0_H_
+#define _DIB07X0_H_
+
+enum dib07x0_gpios {
+       GPIO0  =  0,
+       GPIO1  =  2,
+       GPIO2  =  3,
+       GPIO3  =  4,
+       GPIO4  =  5,
+       GPIO5  =  6,
+       GPIO6  =  8,
+       GPIO7  = 10,
+       GPIO8  = 11,
+       GPIO9  = 14,
+       GPIO10 = 15,
+};
+
+#define GPIO_IN  0
+#define GPIO_OUT 1
+
+#endif
index 124e25ac53b3ce625660ed6819a2d92833fe1ab8..fd3a9902f98d472662f69ee96690c5d11d673814 100644 (file)
@@ -18,12 +18,12 @@ MODULE_LICENSE("GPL");
 #define deb_info(args...) dprintk(debug,0x01,args)
 
 /* common stuff used by the different dibusb modules */
-int dibusb_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+int dibusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 {
-       if (d->priv != NULL) {
-               struct dibusb_state *st = d->priv;
+       if (adap->priv != NULL) {
+               struct dibusb_state *st = adap->priv;
                if (st->ops.fifo_ctrl != NULL)
-                       if (st->ops.fifo_ctrl(d->fe,onoff)) {
+                       if (st->ops.fifo_ctrl(adap->fe,onoff)) {
                                err("error while controlling the fifo of the demod.");
                                return -ENODEV;
                        }
@@ -32,23 +32,23 @@ int dibusb_streaming_ctrl(struct dvb_usb_device *d, int onoff)
 }
 EXPORT_SYMBOL(dibusb_streaming_ctrl);
 
-int dibusb_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff)
+int dibusb_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
 {
-       if (d->priv != NULL) {
-               struct dibusb_state *st = d->priv;
+       if (adap->priv != NULL) {
+               struct dibusb_state *st = adap->priv;
                if (st->ops.pid_ctrl != NULL)
-                       st->ops.pid_ctrl(d->fe,index,pid,onoff);
+                       st->ops.pid_ctrl(adap->fe,index,pid,onoff);
        }
        return 0;
 }
 EXPORT_SYMBOL(dibusb_pid_filter);
 
-int dibusb_pid_filter_ctrl(struct dvb_usb_device *d, int onoff)
+int dibusb_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
 {
-       if (d->priv != NULL) {
-               struct dibusb_state *st = d->priv;
+       if (adap->priv != NULL) {
+               struct dibusb_state *st = adap->priv;
                if (st->ops.pid_parse != NULL)
-                       if (st->ops.pid_parse(d->fe,onoff) < 0)
+                       if (st->ops.pid_parse(adap->fe,onoff) < 0)
                                err("could not handle pid_parser");
        }
        return 0;
@@ -68,24 +68,24 @@ int dibusb_power_ctrl(struct dvb_usb_device *d, int onoff)
 }
 EXPORT_SYMBOL(dibusb_power_ctrl);
 
-int dibusb2_0_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+int dibusb2_0_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 {
        u8 b[3] = { 0 };
        int ret;
 
-       if ((ret = dibusb_streaming_ctrl(d,onoff)) < 0)
+       if ((ret = dibusb_streaming_ctrl(adap,onoff)) < 0)
                return ret;
 
        if (onoff) {
                b[0] = DIBUSB_REQ_SET_STREAMING_MODE;
                b[1] = 0x00;
-               if ((ret = dvb_usb_generic_write(d,b,2)) < 0)
+               if ((ret = dvb_usb_generic_write(adap->dev,b,2)) < 0)
                        return ret;
        }
 
        b[0] = DIBUSB_REQ_SET_IOCTL;
        b[1] = onoff ? DIBUSB_IOCTL_CMD_ENABLE_STREAM : DIBUSB_IOCTL_CMD_DISABLE_STREAM;
-       return dvb_usb_generic_write(d,b,3);
+       return dvb_usb_generic_write(adap->dev,b,3);
 }
 EXPORT_SYMBOL(dibusb2_0_streaming_ctrl);
 
@@ -228,12 +228,12 @@ static struct dib3000mc_config mod3000p_dib3000p_config = {
        .output_mpeg2_in_188_bytes = 1,
 };
 
-int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *d)
+int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *adap)
 {
-       if (dib3000mc_attach(&d->i2c_adap, 1, DEFAULT_DIB3000P_I2C_ADDRESS, 0, &mod3000p_dib3000p_config, &d->fe) == 0 ||
-               dib3000mc_attach(&d->i2c_adap, 1, DEFAULT_DIB3000MC_I2C_ADDRESS, 0, &mod3000p_dib3000p_config, &d->fe) == 0) {
-               if (d->priv != NULL) {
-                       struct dibusb_state *st = d->priv;
+       if ((adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, DEFAULT_DIB3000P_I2C_ADDRESS,  &mod3000p_dib3000p_config)) != NULL ||
+               (adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, DEFAULT_DIB3000MC_I2C_ADDRESS, &mod3000p_dib3000p_config)) != NULL) {
+               if (adap->priv != NULL) {
+                       struct dibusb_state *st = adap->priv;
                        st->ops.pid_parse = dib3000mc_pid_parse;
                        st->ops.pid_ctrl  = dib3000mc_pid_control;
                }
@@ -247,20 +247,19 @@ static struct mt2060_config stk3000p_mt2060_config = {
        0x60
 };
 
-int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *d)
+int dibusb_dib3000mc_tuner_attach(struct dvb_usb_adapter *adap)
 {
-       struct dibusb_state *st = d->priv;
-       int ret;
+       struct dibusb_state *st = adap->priv;
        u8 a,b;
        u16 if1 = 1220;
        struct i2c_adapter *tun_i2c;
 
        // First IF calibration for Liteon Sticks
-       if (d->udev->descriptor.idVendor == USB_VID_LITEON &&
-               d->udev->descriptor.idProduct == USB_PID_LITEON_DVB_T_WARM) {
+       if (adap->dev->udev->descriptor.idVendor  == USB_VID_LITEON &&
+               adap->dev->udev->descriptor.idProduct == USB_PID_LITEON_DVB_T_WARM) {
 
-               dibusb_read_eeprom_byte(d,0x7E,&a);
-               dibusb_read_eeprom_byte(d,0x7F,&b);
+               dibusb_read_eeprom_byte(adap->dev,0x7E,&a);
+               dibusb_read_eeprom_byte(adap->dev,0x7F,&b);
 
                if (a == 0x00)
                        if1 += b;
@@ -269,14 +268,14 @@ int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *d)
                else
                        warn("LITE-ON DVB-T: Strange IF1 calibration :%2X %2X\n", a, b);
 
-       } else if (d->udev->descriptor.idVendor  == USB_VID_DIBCOM &&
-                  d->udev->descriptor.idProduct == USB_PID_DIBCOM_MOD3001_WARM) {
+       } else if (adap->dev->udev->descriptor.idVendor  == USB_VID_DIBCOM &&
+                  adap->dev->udev->descriptor.idProduct == USB_PID_DIBCOM_MOD3001_WARM) {
                u8 desc;
-               dibusb_read_eeprom_byte(d, 7, &desc);
+               dibusb_read_eeprom_byte(adap->dev, 7, &desc);
                if (desc == 2) {
                        a = 127;
                        do {
-                               dibusb_read_eeprom_byte(d, a, &desc);
+                               dibusb_read_eeprom_byte(adap->dev, a, &desc);
                                a--;
                        } while (a > 7 && (desc == 0xff || desc == 0x00));
                        if (desc & 0x80)
@@ -286,15 +285,15 @@ int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *d)
                }
        }
 
-       tun_i2c = dib3000mc_get_tuner_i2c_master(d->fe, 1);
-       if ((ret = mt2060_attach(d->fe, tun_i2c, &stk3000p_mt2060_config, if1)) != 0) {
+       tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe, 1);
+       if (dvb_attach(mt2060_attach, adap->fe, tun_i2c, &stk3000p_mt2060_config, if1) == NULL) {
                /* not found - use panasonic pll parameters */
-               if (dvb_pll_attach(d->fe, 0x60, tun_i2c, &dvb_pll_env57h1xd5) == NULL)
+               if (dvb_attach(dvb_pll_attach, adap->fe, 0x60, tun_i2c, &dvb_pll_env57h1xd5) == NULL)
                        return -ENOMEM;
        } else {
                st->mt2060_present = 1;
                /* set the correct parameters for the dib3000p */
-               dib3000mc_set_config(d->fe, &stk3000p_dib3000p_config);
+               dib3000mc_set_config(adap->fe, &stk3000p_dib3000p_config);
        }
        return 0;
 }
index effd34cc4b02d23601086904734a3b0ce78db57c..4fe363e48352b753b0359706bc33c3731582fb36 100644 (file)
  */
 #include "dibusb.h"
 
-static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_device *d)
+static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_adapter *adap)
 {
        struct dib3000_config demod_cfg;
-       struct dibusb_state *st = d->priv;
+       struct dibusb_state *st = adap->priv;
 
        demod_cfg.demod_address = 0x8;
 
-       if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL)
+       if ((adap->fe = dib3000mb_attach(&demod_cfg,&adap->dev->i2c_adap,&st->ops)) == NULL)
                return -ENODEV;
 
-       d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c;
-       d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
+       adap->fe->ops.tuner_ops.init       = dvb_usb_tuner_init_i2c;
+       adap->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
 
-       d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl;
+       adap->tuner_pass_ctrl = st->ops.tuner_pass_ctrl;
 
        return 0;
 }
 
-static int dibusb_thomson_tuner_attach(struct dvb_usb_device *d)
+static int dibusb_thomson_tuner_attach(struct dvb_usb_adapter *adap)
 {
-       d->pll_addr = 0x61;
-       d->pll_desc = &dvb_pll_tua6010xs;
+       adap->pll_addr = 0x61;
+       adap->pll_desc = &dvb_pll_tua6010xs;
        return 0;
 }
 
 /* Some of the Artec 1.1 device aren't equipped with the default tuner
  * (Thomson Cable), but with a Panasonic ENV77H11D5.  This function figures
  * this out. */
-static int dibusb_tuner_probe_and_attach(struct dvb_usb_device *d)
+static int dibusb_tuner_probe_and_attach(struct dvb_usb_adapter *adap)
 {
        u8 b[2] = { 0,0 }, b2[1];
        int ret = 0;
@@ -54,36 +54,36 @@ static int dibusb_tuner_probe_and_attach(struct dvb_usb_device *d)
        /* the Panasonic sits on I2C addrass 0x60, the Thomson on 0x61 */
        msg[0].addr = msg[1].addr = 0x60;
 
-       if (d->tuner_pass_ctrl)
-               d->tuner_pass_ctrl(d->fe,1,msg[0].addr);
+       if (adap->tuner_pass_ctrl)
+               adap->tuner_pass_ctrl(adap->fe,1,msg[0].addr);
 
-       if (i2c_transfer (&d->i2c_adap, msg, 2) != 2) {
+       if (i2c_transfer(&adap->dev->i2c_adap, msg, 2) != 2) {
                err("tuner i2c write failed.");
                ret = -EREMOTEIO;
        }
 
-       if (d->tuner_pass_ctrl)
-               d->tuner_pass_ctrl(d->fe,0,msg[0].addr);
+       if (adap->tuner_pass_ctrl)
+               adap->tuner_pass_ctrl(adap->fe,0,msg[0].addr);
 
        if (b2[0] == 0xfe) {
                info("This device has the Thomson Cable onboard. Which is default.");
-               dibusb_thomson_tuner_attach(d);
+               dibusb_thomson_tuner_attach(adap);
        } else {
                u8 bpll[4] = { 0x0b, 0xf5, 0x85, 0xab };
                info("This device has the Panasonic ENV77H11D5 onboard.");
-               d->pll_addr = 0x60;
-               memcpy(d->pll_init,bpll,4);
-               d->pll_desc = &dvb_pll_tda665x;
+               adap->pll_addr = 0x60;
+               memcpy(adap->pll_init,bpll,4);
+               adap->pll_desc = &dvb_pll_tda665x;
        }
 
        return ret;
 }
 
 /* USB Driver stuff */
-static struct dvb_usb_properties dibusb1_1_properties;
-static struct dvb_usb_properties dibusb1_1_an2235_properties;
-static struct dvb_usb_properties dibusb2_0b_properties;
-static struct dvb_usb_properties artec_t1_usb2_properties;
+static struct dvb_usb_device_properties dibusb1_1_properties;
+static struct dvb_usb_device_properties dibusb1_1_an2235_properties;
+static struct dvb_usb_device_properties dibusb2_0b_properties;
+static struct dvb_usb_device_properties artec_t1_usb2_properties;
 
 static int dibusb_probe(struct usb_interface *intf,
                const struct usb_device_id *id)
@@ -150,34 +150,28 @@ static struct usb_device_id dibusb_dib3000mb_table [] = {
 };
 MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table);
 
-static struct dvb_usb_properties dibusb1_1_properties = {
-       .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
-       .pid_filter_count = 16,
+static struct dvb_usb_device_properties dibusb1_1_properties = {
+       .caps =  DVB_USB_IS_AN_I2C_ADAPTER,
 
        .usb_ctrl = CYPRESS_AN2135,
 
        .firmware = "dvb-usb-dibusb-5.0.0.11.fw",
 
-       .size_of_priv     = sizeof(struct dibusb_state),
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                       .pid_filter_count = 16,
 
        .streaming_ctrl   = dibusb_streaming_ctrl,
        .pid_filter       = dibusb_pid_filter,
        .pid_filter_ctrl  = dibusb_pid_filter_ctrl,
-       .power_ctrl       = dibusb_power_ctrl,
        .frontend_attach  = dibusb_dib3000mb_frontend_attach,
        .tuner_attach     = dibusb_tuner_probe_and_attach,
 
-       .rc_interval      = DEFAULT_RC_INTERVAL,
-       .rc_key_map       = dibusb_rc_keys,
-       .rc_key_map_size  = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
-       .rc_query         = dibusb_rc_query,
-
-       .i2c_algo         = &dibusb_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
        /* parameter for the MPEG2-data transfer */
-       .urb = {
-               .type = DVB_USB_BULK,
+                       .stream = {
+                               .type = USB_BULK,
                .count = 7,
                .endpoint = 0x02,
                .u = {
@@ -186,6 +180,20 @@ static struct dvb_usb_properties dibusb1_1_properties = {
                        }
                }
        },
+                       .size_of_priv     = sizeof(struct dibusb_state),
+               }
+       },
+
+       .power_ctrl       = dibusb_power_ctrl,
+
+       .rc_interval      = DEFAULT_RC_INTERVAL,
+       .rc_key_map       = dibusb_rc_keys,
+       .rc_key_map_size  = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
+       .rc_query         = dibusb_rc_query,
+
+       .i2c_algo         = &dibusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
 
        .num_device_descs = 9,
        .devices = {
@@ -228,34 +236,27 @@ static struct dvb_usb_properties dibusb1_1_properties = {
        }
 };
 
-static struct dvb_usb_properties dibusb1_1_an2235_properties = {
-       .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
-       .pid_filter_count = 16,
-
+static struct dvb_usb_device_properties dibusb1_1_an2235_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
        .usb_ctrl = CYPRESS_AN2235,
 
        .firmware = "dvb-usb-dibusb-an2235-01.fw",
 
-       .size_of_priv     = sizeof(struct dibusb_state),
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .caps = DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_ADAP_HAS_PID_FILTER,
+                       .pid_filter_count = 16,
 
        .streaming_ctrl   = dibusb_streaming_ctrl,
        .pid_filter       = dibusb_pid_filter,
        .pid_filter_ctrl  = dibusb_pid_filter_ctrl,
-       .power_ctrl       = dibusb_power_ctrl,
        .frontend_attach  = dibusb_dib3000mb_frontend_attach,
        .tuner_attach     = dibusb_tuner_probe_and_attach,
 
-       .rc_interval      = DEFAULT_RC_INTERVAL,
-       .rc_key_map       = dibusb_rc_keys,
-       .rc_key_map_size  = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
-       .rc_query         = dibusb_rc_query,
-
-       .i2c_algo         = &dibusb_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
        /* parameter for the MPEG2-data transfer */
-       .urb = {
-               .type = DVB_USB_BULK,
+                       .stream = {
+                               .type = USB_BULK,
                .count = 7,
                .endpoint = 0x02,
                .u = {
@@ -264,6 +265,19 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
                        }
                }
        },
+                       .size_of_priv     = sizeof(struct dibusb_state),
+               },
+       },
+       .power_ctrl       = dibusb_power_ctrl,
+
+       .rc_interval      = DEFAULT_RC_INTERVAL,
+       .rc_key_map       = dibusb_rc_keys,
+       .rc_key_map_size  = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
+       .rc_query         = dibusb_rc_query,
+
+       .i2c_algo         = &dibusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
 
 #ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
        .num_device_descs = 2,
@@ -285,34 +299,27 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
        }
 };
 
-static struct dvb_usb_properties dibusb2_0b_properties = {
-       .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
-       .pid_filter_count = 16,
+static struct dvb_usb_device_properties dibusb2_0b_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
        .usb_ctrl = CYPRESS_FX2,
 
        .firmware = "dvb-usb-adstech-usb2-02.fw",
 
-       .size_of_priv     = sizeof(struct dibusb_state),
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                       .pid_filter_count = 16,
 
        .streaming_ctrl   = dibusb2_0_streaming_ctrl,
        .pid_filter       = dibusb_pid_filter,
        .pid_filter_ctrl  = dibusb_pid_filter_ctrl,
-       .power_ctrl       = dibusb2_0_power_ctrl,
        .frontend_attach  = dibusb_dib3000mb_frontend_attach,
        .tuner_attach     = dibusb_thomson_tuner_attach,
-
-       .rc_interval      = DEFAULT_RC_INTERVAL,
-       .rc_key_map       = dibusb_rc_keys,
-       .rc_key_map_size  = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
-       .rc_query         = dibusb_rc_query,
-
-       .i2c_algo         = &dibusb_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
        /* parameter for the MPEG2-data transfer */
-       .urb = {
-               .type = DVB_USB_BULK,
+                       .stream = {
+                               .type = USB_BULK,
                .count = 7,
                .endpoint = 0x06,
                .u = {
@@ -321,6 +328,19 @@ static struct dvb_usb_properties dibusb2_0b_properties = {
                        }
                }
        },
+                       .size_of_priv     = sizeof(struct dibusb_state),
+               }
+       },
+       .power_ctrl       = dibusb2_0_power_ctrl,
+
+       .rc_interval      = DEFAULT_RC_INTERVAL,
+       .rc_key_map       = dibusb_rc_keys,
+       .rc_key_map_size  = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
+       .rc_query         = dibusb_rc_query,
+
+       .i2c_algo         = &dibusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
 
        .num_device_descs = 2,
        .devices = {
@@ -336,34 +356,27 @@ static struct dvb_usb_properties dibusb2_0b_properties = {
        }
 };
 
-static struct dvb_usb_properties artec_t1_usb2_properties = {
-       .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
-       .pid_filter_count = 16,
+static struct dvb_usb_device_properties artec_t1_usb2_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
        .usb_ctrl = CYPRESS_FX2,
 
        .firmware = "dvb-usb-dibusb-6.0.0.8.fw",
 
-       .size_of_priv     = sizeof(struct dibusb_state),
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                       .pid_filter_count = 16,
 
        .streaming_ctrl   = dibusb2_0_streaming_ctrl,
        .pid_filter       = dibusb_pid_filter,
        .pid_filter_ctrl  = dibusb_pid_filter_ctrl,
-       .power_ctrl       = dibusb2_0_power_ctrl,
        .frontend_attach  = dibusb_dib3000mb_frontend_attach,
        .tuner_attach     = dibusb_tuner_probe_and_attach,
-
-       .rc_interval      = DEFAULT_RC_INTERVAL,
-       .rc_key_map       = dibusb_rc_keys,
-       .rc_key_map_size  = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
-       .rc_query         = dibusb_rc_query,
-
-       .i2c_algo         = &dibusb_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
        /* parameter for the MPEG2-data transfer */
-       .urb = {
-               .type = DVB_USB_BULK,
+                       .stream = {
+                               .type = USB_BULK,
                .count = 7,
                .endpoint = 0x06,
                .u = {
@@ -372,6 +385,19 @@ static struct dvb_usb_properties artec_t1_usb2_properties = {
                        }
                }
        },
+                       .size_of_priv     = sizeof(struct dibusb_state),
+               }
+       },
+       .power_ctrl       = dibusb2_0_power_ctrl,
+
+       .rc_interval      = DEFAULT_RC_INTERVAL,
+       .rc_key_map       = dibusb_rc_keys,
+       .rc_key_map_size  = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
+       .rc_query         = dibusb_rc_query,
+
+       .i2c_algo         = &dibusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
 
        .num_device_descs = 1,
        .devices = {
index eca4082a61ae4920b0e49b045b4d55ab21f6e837..a0fd37efc04b0706a92c7bc192e00571d65528d6 100644 (file)
@@ -15,7 +15,7 @@
 #include "dibusb.h"
 
 /* USB Driver stuff */
-static struct dvb_usb_properties dibusb_mc_properties;
+static struct dvb_usb_device_properties dibusb_mc_properties;
 
 static int dibusb_mc_probe(struct usb_interface *intf,
                const struct usb_device_id *id)
@@ -43,33 +43,26 @@ static struct usb_device_id dibusb_dib3000mc_table [] = {
 };
 MODULE_DEVICE_TABLE (usb, dibusb_dib3000mc_table);
 
-static struct dvb_usb_properties dibusb_mc_properties = {
-       .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
-       .pid_filter_count = 32,
+static struct dvb_usb_device_properties dibusb_mc_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
        .usb_ctrl = CYPRESS_FX2,
        .firmware = "dvb-usb-dibusb-6.0.0.8.fw",
 
-       .size_of_priv     = sizeof(struct dibusb_state),
-
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                       .pid_filter_count = 32,
        .streaming_ctrl   = dibusb2_0_streaming_ctrl,
        .pid_filter       = dibusb_pid_filter,
        .pid_filter_ctrl  = dibusb_pid_filter_ctrl,
-       .power_ctrl       = dibusb2_0_power_ctrl,
        .frontend_attach  = dibusb_dib3000mc_frontend_attach,
        .tuner_attach     = dibusb_dib3000mc_tuner_attach,
 
-       .rc_interval      = DEFAULT_RC_INTERVAL,
-       .rc_key_map       = dibusb_rc_keys,
-       .rc_key_map_size  = 111, /* FIXME */
-       .rc_query         = dibusb_rc_query,
-
-       .i2c_algo         = &dibusb_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
        /* parameter for the MPEG2-data transfer */
-       .urb = {
-               .type = DVB_USB_BULK,
+                       .stream = {
+                               .type = USB_BULK,
                .count = 7,
                .endpoint = 0x06,
                .u = {
@@ -78,6 +71,19 @@ static struct dvb_usb_properties dibusb_mc_properties = {
                        }
                }
        },
+                       .size_of_priv     = sizeof(struct dibusb_state),
+               }
+       },
+       .power_ctrl       = dibusb2_0_power_ctrl,
+
+       .rc_interval      = DEFAULT_RC_INTERVAL,
+       .rc_key_map       = dibusb_rc_keys,
+       .rc_key_map_size  = 111, /* FIXME */
+       .rc_query         = dibusb_rc_query,
+
+       .i2c_algo         = &dibusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
 
        .num_device_descs = 7,
        .devices = {
index a43f87480cf608810a20c9c320a5f764770780e4..5153fb943da1fce0e429648acb495d644e2cba7c 100644 (file)
@@ -107,14 +107,15 @@ struct dibusb_state {
 
 extern struct i2c_algorithm dibusb_i2c_algo;
 
-extern int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *);
-extern int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *);
+extern int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *);
+extern int dibusb_dib3000mc_tuner_attach (struct dvb_usb_adapter *);
+
+extern int dibusb_streaming_ctrl(struct dvb_usb_adapter *, int);
+extern int dibusb_pid_filter(struct dvb_usb_adapter *, int, u16, int);
+extern int dibusb_pid_filter_ctrl(struct dvb_usb_adapter *, int);
+extern int dibusb2_0_streaming_ctrl(struct dvb_usb_adapter *, int);
 
-extern int dibusb_streaming_ctrl(struct dvb_usb_device *, int);
-extern int dibusb_pid_filter(struct dvb_usb_device *, int, u16, int);
-extern int dibusb_pid_filter_ctrl(struct dvb_usb_device *, int);
 extern int dibusb_power_ctrl(struct dvb_usb_device *, int);
-extern int dibusb2_0_streaming_ctrl(struct dvb_usb_device *, int);
 extern int dibusb2_0_power_ctrl(struct dvb_usb_device *, int);
 
 #define DEFAULT_RC_INTERVAL 150
index 015854487308b7b7f9c452dd429eb002d1350a3f..8fb34375c1fbeb1548c931de9b00cc419e88117d 100644 (file)
@@ -83,7 +83,7 @@ static struct i2c_algorithm digitv_i2c_algo = {
 
 /* Callbacks for DVB USB */
 static int digitv_identify_state (struct usb_device *udev, struct
-               dvb_usb_properties *props, struct dvb_usb_device_description **desc,
+               dvb_usb_device_properties *props, struct dvb_usb_device_description **desc,
                int *cold)
 {
        *cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0;
@@ -116,33 +116,33 @@ static struct mt352_config digitv_mt352_config = {
 
 static int digitv_nxt6000_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
 {
-       struct dvb_usb_device *d = fe->dvb->priv;
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
        u8 b[5];
        dvb_usb_tuner_calc_regs(fe,fep,b, 5);
-       return digitv_ctrl_msg(d,USB_WRITE_TUNER,0,&b[1],4,NULL,0);
+       return digitv_ctrl_msg(adap->dev, USB_WRITE_TUNER, 0, &b[1], 4, NULL, 0);
 }
 
 static struct nxt6000_config digitv_nxt6000_config = {
        .clock_inversion = 1,
 };
 
-static int digitv_frontend_attach(struct dvb_usb_device *d)
+static int digitv_frontend_attach(struct dvb_usb_adapter *adap)
 {
-       if ((d->fe = dvb_attach(mt352_attach, &digitv_mt352_config, &d->i2c_adap)) != NULL) {
-               d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
+       if ((adap->fe = dvb_attach(mt352_attach, &digitv_mt352_config, &adap->dev->i2c_adap)) != NULL) {
+               adap->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
                return 0;
        }
-       if ((d->fe = dvb_attach(nxt6000_attach, &digitv_nxt6000_config, &d->i2c_adap)) != NULL) {
-               d->fe->ops.tuner_ops.set_params = digitv_nxt6000_tuner_set_params;
+       if ((adap->fe = dvb_attach(nxt6000_attach, &digitv_nxt6000_config, &adap->dev->i2c_adap)) != NULL) {
+               adap->fe->ops.tuner_ops.set_params = digitv_nxt6000_tuner_set_params;
                return 0;
        }
        return -EIO;
 }
 
-static int digitv_tuner_attach(struct dvb_usb_device *d)
+static int digitv_tuner_attach(struct dvb_usb_adapter *adap)
 {
-       d->pll_addr = 0x60;
-       d->pll_desc = &dvb_pll_tded4;
+       adap->pll_addr = 0x60;
+       adap->pll_desc = &dvb_pll_tded4;
        return 0;
 }
 
@@ -238,7 +238,7 @@ static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 }
 
 /* DVB USB Driver stuff */
-static struct dvb_usb_properties digitv_properties;
+static struct dvb_usb_device_properties digitv_properties;
 
 static int digitv_probe(struct usb_interface *intf,
                const struct usb_device_id *id)
@@ -265,30 +265,21 @@ static struct usb_device_id digitv_table [] = {
 };
 MODULE_DEVICE_TABLE (usb, digitv_table);
 
-static struct dvb_usb_properties digitv_properties = {
+static struct dvb_usb_device_properties digitv_properties = {
        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
        .usb_ctrl = CYPRESS_FX2,
        .firmware = "dvb-usb-digitv-02.fw",
 
-       .size_of_priv     = 0,
-
+       .num_adapters = 1,
+       .adapter = {
+               {
        .frontend_attach  = digitv_frontend_attach,
        .tuner_attach     = digitv_tuner_attach,
 
-       .rc_interval      = 1000,
-       .rc_key_map       = digitv_rc_keys,
-       .rc_key_map_size  = ARRAY_SIZE(digitv_rc_keys),
-       .rc_query         = digitv_rc_query,
-
-       .identify_state   = digitv_identify_state,
-
-       .i2c_algo         = &digitv_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
        /* parameter for the MPEG2-data transfer */
-       .urb = {
-               .type = DVB_USB_BULK,
+                       .stream = {
+                               .type = USB_BULK,
                .count = 7,
                .endpoint = 0x02,
                .u = {
@@ -297,6 +288,18 @@ static struct dvb_usb_properties digitv_properties = {
                        }
                }
        },
+               }
+       },
+       .identify_state   = digitv_identify_state,
+
+       .rc_interval      = 1000,
+       .rc_key_map       = digitv_rc_keys,
+       .rc_key_map_size  = ARRAY_SIZE(digitv_rc_keys),
+       .rc_query         = digitv_rc_query,
+
+       .i2c_algo         = &digitv_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
 
        .num_device_descs = 1,
        .devices = {
index 27af4e43647936fe72a6db60704fcb5eaa804068..fa43a41d753b6a8b1e99b9e7512aaf83141699f8 100644 (file)
@@ -28,19 +28,19 @@ static int dtt200u_power_ctrl(struct dvb_usb_device *d, int onoff)
        return 0;
 }
 
-static int dtt200u_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+static int dtt200u_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 {
        u8 b_streaming[2] = { SET_STREAMING, onoff };
        u8 b_rst_pid = RESET_PID_FILTER;
 
-       dvb_usb_generic_write(d,b_streaming,2);
+       dvb_usb_generic_write(adap->dev, b_streaming, 2);
 
        if (onoff == 0)
-               dvb_usb_generic_write(d,&b_rst_pid,1);
+               dvb_usb_generic_write(adap->dev, &b_rst_pid, 1);
        return 0;
 }
 
-static int dtt200u_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff)
+static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
 {
        u8 b_pid[4];
        pid = onoff ? pid : 0;
@@ -50,7 +50,7 @@ static int dtt200u_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int
        b_pid[2] = pid & 0xff;
        b_pid[3] = (pid >> 8) & 0x1f;
 
-       return dvb_usb_generic_write(d,b_pid,4);
+       return dvb_usb_generic_write(adap->dev, b_pid, 4);
 }
 
 /* remote control */
@@ -86,16 +86,16 @@ static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
        return 0;
 }
 
-static int dtt200u_frontend_attach(struct dvb_usb_device *d)
+static int dtt200u_frontend_attach(struct dvb_usb_adapter *adap)
 {
-       d->fe = dtt200u_fe_attach(d);
+       adap->fe = dtt200u_fe_attach(adap->dev);
        return 0;
 }
 
-static struct dvb_usb_properties dtt200u_properties;
-static struct dvb_usb_properties wt220u_fc_properties;
-static struct dvb_usb_properties wt220u_properties;
-static struct dvb_usb_properties wt220u_zl0353_properties;
+static struct dvb_usb_device_properties dtt200u_properties;
+static struct dvb_usb_device_properties wt220u_fc_properties;
+static struct dvb_usb_device_properties wt220u_properties;
+static struct dvb_usb_device_properties wt220u_zl0353_properties;
 
 static int dtt200u_usb_probe(struct usb_interface *intf,
                const struct usb_device_id *id)
@@ -123,28 +123,22 @@ static struct usb_device_id dtt200u_usb_table [] = {
 };
 MODULE_DEVICE_TABLE(usb, dtt200u_usb_table);
 
-static struct dvb_usb_properties dtt200u_properties = {
-       .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
-       .pid_filter_count = 15,
-
+static struct dvb_usb_device_properties dtt200u_properties = {
        .usb_ctrl = CYPRESS_FX2,
        .firmware = "dvb-usb-dtt200u-01.fw",
 
-       .power_ctrl      = dtt200u_power_ctrl,
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
+                       .pid_filter_count = 15,
+
        .streaming_ctrl  = dtt200u_streaming_ctrl,
        .pid_filter      = dtt200u_pid_filter,
        .frontend_attach = dtt200u_frontend_attach,
-
-       .rc_interval     = 300,
-       .rc_key_map      = dtt200u_rc_keys,
-       .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
-       .rc_query        = dtt200u_rc_query,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
        /* parameter for the MPEG2-data transfer */
-       .urb = {
-               .type = DVB_USB_BULK,
+                       .stream = {
+                               .type = USB_BULK,
                .count = 7,
                .endpoint = 0x02,
                .u = {
@@ -153,6 +147,16 @@ static struct dvb_usb_properties dtt200u_properties = {
                        }
                }
        },
+               }
+       },
+       .power_ctrl      = dtt200u_power_ctrl,
+
+       .rc_interval     = 300,
+       .rc_key_map      = dtt200u_rc_keys,
+       .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
+       .rc_query        = dtt200u_rc_query,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
 
        .num_device_descs = 1,
        .devices = {
@@ -164,28 +168,22 @@ static struct dvb_usb_properties dtt200u_properties = {
        }
 };
 
-static struct dvb_usb_properties wt220u_properties = {
-       .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
-       .pid_filter_count = 15,
-
+static struct dvb_usb_device_properties wt220u_properties = {
        .usb_ctrl = CYPRESS_FX2,
        .firmware = "dvb-usb-wt220u-02.fw",
 
-       .power_ctrl      = dtt200u_power_ctrl,
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
+                       .pid_filter_count = 15,
+
        .streaming_ctrl  = dtt200u_streaming_ctrl,
        .pid_filter      = dtt200u_pid_filter,
        .frontend_attach = dtt200u_frontend_attach,
-
-       .rc_interval     = 300,
-       .rc_key_map      = dtt200u_rc_keys,
-       .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
-       .rc_query        = dtt200u_rc_query,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
        /* parameter for the MPEG2-data transfer */
-       .urb = {
-               .type = DVB_USB_BULK,
+                       .stream = {
+                               .type = USB_BULK,
                .count = 7,
                .endpoint = 0x02,
                .u = {
@@ -194,6 +192,16 @@ static struct dvb_usb_properties wt220u_properties = {
                        }
                }
        },
+               }
+       },
+       .power_ctrl      = dtt200u_power_ctrl,
+
+       .rc_interval     = 300,
+       .rc_key_map      = dtt200u_rc_keys,
+       .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
+       .rc_query        = dtt200u_rc_query,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
 
        .num_device_descs = 1,
        .devices = {
@@ -205,36 +213,40 @@ static struct dvb_usb_properties wt220u_properties = {
        }
 };
 
-static struct dvb_usb_properties wt220u_fc_properties = {
-       .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
-       .pid_filter_count = 15,
-
+static struct dvb_usb_device_properties wt220u_fc_properties = {
        .usb_ctrl = CYPRESS_FX2,
        .firmware = "dvb-usb-wt220u-fc03.fw",
 
-       .power_ctrl      = dtt200u_power_ctrl,
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
+                       .pid_filter_count = 15,
+
        .streaming_ctrl  = dtt200u_streaming_ctrl,
        .pid_filter      = dtt200u_pid_filter,
        .frontend_attach = dtt200u_frontend_attach,
-
-       .rc_interval     = 300,
-       .rc_key_map      = dtt200u_rc_keys,
-       .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
-       .rc_query        = dtt200u_rc_query,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
        /* parameter for the MPEG2-data transfer */
-       .urb = {
-               .type = DVB_USB_BULK,
+                       .stream = {
+                               .type = USB_BULK,
                .count = 7,
-               .endpoint = 0x86,
+                               .endpoint = 0x06,
                .u = {
                        .bulk = {
                                .buffersize = 4096,
                        }
                }
        },
+               }
+       },
+       .power_ctrl      = dtt200u_power_ctrl,
+
+       .rc_interval     = 300,
+       .rc_key_map      = dtt200u_rc_keys,
+       .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
+       .rc_query        = dtt200u_rc_query,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
 
        .num_device_descs = 1,
        .devices = {
@@ -246,28 +258,22 @@ static struct dvb_usb_properties wt220u_fc_properties = {
        }
 };
 
-static struct dvb_usb_properties wt220u_zl0353_properties = {
-       .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
-       .pid_filter_count = 15,
-
+static struct dvb_usb_device_properties wt220u_zl0353_properties = {
        .usb_ctrl = CYPRESS_FX2,
        .firmware = "dvb-usb-wt220u-zl0353-01.fw",
 
-       .power_ctrl      = dtt200u_power_ctrl,
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
+                       .pid_filter_count = 15,
+
        .streaming_ctrl  = dtt200u_streaming_ctrl,
        .pid_filter      = dtt200u_pid_filter,
        .frontend_attach = dtt200u_frontend_attach,
-
-       .rc_interval     = 300,
-       .rc_key_map      = dtt200u_rc_keys,
-       .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
-       .rc_query        = dtt200u_rc_query,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-
        /* parameter for the MPEG2-data transfer */
-       .urb = {
-               .type = DVB_USB_BULK,
+                       .stream = {
+                               .type = USB_BULK,
                .count = 7,
                .endpoint = 0x02,
                .u = {
@@ -276,6 +282,16 @@ static struct dvb_usb_properties wt220u_zl0353_properties = {
                        }
                }
        },
+               }
+       },
+       .power_ctrl      = dtt200u_power_ctrl,
+
+       .rc_interval     = 300,
+       .rc_key_map      = dtt200u_rc_keys,
+       .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
+       .rc_query        = dtt200u_rc_query,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
 
        .num_device_descs = 1,
        .devices = {
index a3460bf2d9fa56eb1ab4495678a51ede6b0d4b63..35ab68f6dcf6346e5748e775c95a722c478295e5 100644 (file)
 extern int dvb_usb_debug;
 extern int dvb_usb_disable_rc_polling;
 
-#define deb_info(args...) dprintk(dvb_usb_debug,0x01,args)
-#define deb_xfer(args...) dprintk(dvb_usb_debug,0x02,args)
-#define deb_pll(args...)  dprintk(dvb_usb_debug,0x04,args)
-#define deb_ts(args...)   dprintk(dvb_usb_debug,0x08,args)
-#define deb_err(args...)  dprintk(dvb_usb_debug,0x10,args)
-#define deb_rc(args...)   dprintk(dvb_usb_debug,0x20,args)
-#define deb_fw(args...)   dprintk(dvb_usb_debug,0x40,args)
-#define deb_mem(args...)  dprintk(dvb_usb_debug,0x80,args)
+#define deb_info(args...)  dprintk(dvb_usb_debug,0x001,args)
+#define deb_xfer(args...)  dprintk(dvb_usb_debug,0x002,args)
+#define deb_pll(args...)   dprintk(dvb_usb_debug,0x004,args)
+#define deb_ts(args...)    dprintk(dvb_usb_debug,0x008,args)
+#define deb_err(args...)   dprintk(dvb_usb_debug,0x010,args)
+#define deb_rc(args...)    dprintk(dvb_usb_debug,0x020,args)
+#define deb_fw(args...)    dprintk(dvb_usb_debug,0x040,args)
+#define deb_mem(args...)   dprintk(dvb_usb_debug,0x080,args)
+#define deb_uxfer(args...) dprintk(dvb_usb_debug,0x100,args)
 
 /* commonly used  methods */
-extern int dvb_usb_download_firmware(struct usb_device *, struct dvb_usb_properties *);
+extern int dvb_usb_download_firmware(struct usb_device *, struct dvb_usb_device_properties *);
 
-extern int dvb_usb_urb_submit(struct dvb_usb_device *);
-extern int dvb_usb_urb_kill(struct dvb_usb_device *);
-extern int dvb_usb_urb_init(struct dvb_usb_device *);
-extern int dvb_usb_urb_exit(struct dvb_usb_device *);
+extern int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff);
+
+extern int usb_urb_init(struct usb_data_stream *stream, struct usb_data_stream_properties *props);
+extern int usb_urb_exit(struct usb_data_stream *stream);
+extern int usb_urb_submit(struct usb_data_stream *stream);
+extern int usb_urb_kill(struct usb_data_stream *stream);
+
+extern int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap);
+extern int dvb_usb_adapter_stream_exit(struct dvb_usb_adapter *adap);
 
 extern int dvb_usb_i2c_init(struct dvb_usb_device *);
 extern int dvb_usb_i2c_exit(struct dvb_usb_device *);
 
-extern int dvb_usb_dvb_init(struct dvb_usb_device *);
-extern int dvb_usb_dvb_exit(struct dvb_usb_device *);
-
-extern int dvb_usb_fe_init(struct dvb_usb_device *);
-extern int dvb_usb_fe_exit(struct dvb_usb_device *);
+extern int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap);
+extern int dvb_usb_adapter_dvb_exit(struct dvb_usb_adapter *adap);
+extern int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap);
+extern int dvb_usb_adapter_frontend_exit(struct dvb_usb_adapter *adap);
 
 extern int dvb_usb_remote_init(struct dvb_usb_device *);
 extern int dvb_usb_remote_exit(struct dvb_usb_device *);
index fe6208ada9037c916ffdb62c594bbe1a9f3b7dd6..4561a672da924c70ab9ba121c056b4591b1f55e4 100644 (file)
@@ -1,6 +1,6 @@
 /* dvb-usb-dvb.c is part of the DVB USB library.
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
  * see dvb-usb-init.c for copyright information.
  *
  * This file contains functions for initializing and handling the
@@ -8,55 +8,55 @@
  */
 #include "dvb-usb-common.h"
 
+/* does the complete input transfer handling */
 static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
 {
-       struct dvb_usb_device *d = dvbdmxfeed->demux->priv;
+       struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv;
        int newfeedcount,ret;
 
-       if (d == NULL)
+       if (adap == NULL)
                return -ENODEV;
 
-       newfeedcount = d->feedcount + (onoff ? 1 : -1);
+       newfeedcount = adap->feedcount + (onoff ? 1 : -1);
 
-       /*
-        * stop feed before setting a new pid if there will be no pid anymore
-        */
+       /* stop feed before setting a new pid if there will be no pid anymore */
        if (newfeedcount == 0) {
                deb_ts("stop feeding\n");
-               dvb_usb_urb_kill(d);
+               usb_urb_kill(&adap->stream);
 
-               if (d->props.streaming_ctrl != NULL)
-                       if ((ret = d->props.streaming_ctrl(d,0)))
+               if (adap->props.streaming_ctrl != NULL)
+                       if ((ret = adap->props.streaming_ctrl(adap,0)))
                                err("error while stopping stream.");
-
        }
 
-       d->feedcount = newfeedcount;
+       adap->feedcount = newfeedcount;
 
        /* activate the pid on the device specific pid_filter */
-       deb_ts("setting pid: %5d %04x at index %d '%s'\n",dvbdmxfeed->pid,dvbdmxfeed->pid,dvbdmxfeed->index,onoff ? "on" : "off");
-       if (d->props.caps & DVB_USB_HAS_PID_FILTER &&
-               d->pid_filtering &&
-               d->props.pid_filter != NULL)
-               d->props.pid_filter(d,dvbdmxfeed->index,dvbdmxfeed->pid,onoff);
+       deb_ts("setting pid (%s): %5d %04x at index %d '%s'\n",adap->pid_filtering ?
+               "yes" : "no", dvbdmxfeed->pid,dvbdmxfeed->pid,dvbdmxfeed->index,onoff ?
+               "on" : "off");
+       if (adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER &&
+               adap->pid_filtering &&
+               adap->props.pid_filter != NULL)
+               adap->props.pid_filter(adap, dvbdmxfeed->index, dvbdmxfeed->pid,onoff);
 
        /* start the feed if this was the first feed and there is still a feed
         * for reception.
         */
-       if (d->feedcount == onoff && d->feedcount > 0) {
+       if (adap->feedcount == onoff && adap->feedcount > 0) {
                deb_ts("submitting all URBs\n");
-               dvb_usb_urb_submit(d);
+               usb_urb_submit(&adap->stream);
 
                deb_ts("controlling pid parser\n");
-               if (d->props.caps & DVB_USB_HAS_PID_FILTER &&
-                       d->props.caps & DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF &&
-                       d->props.pid_filter_ctrl != NULL)
-                       if (d->props.pid_filter_ctrl(d,d->pid_filtering) < 0)
+               if (adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER &&
+                       adap->props.caps & DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF &&
+                       adap->props.pid_filter_ctrl != NULL)
+                       if (adap->props.pid_filter_ctrl(adap,adap->pid_filtering) < 0)
                                err("could not handle pid_parser");
 
                deb_ts("start feeding\n");
-               if (d->props.streaming_ctrl != NULL)
-                       if (d->props.streaming_ctrl(d,1)) {
+               if (adap->props.streaming_ctrl != NULL)
+                       if (adap->props.streaming_ctrl(adap,1)) {
                                err("error while enabling fifo.");
                                return -ENODEV;
                        }
@@ -77,134 +77,130 @@ static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
        return dvb_usb_ctrl_feed(dvbdmxfeed,0);
 }
 
-int dvb_usb_dvb_init(struct dvb_usb_device *d)
+int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap)
 {
        int ret;
 
-       if ((ret = dvb_register_adapter(&d->dvb_adap, d->desc->name,
-                       d->owner, &d->udev->dev)) < 0) {
+       if ((ret = dvb_register_adapter(&adap->dvb_adap, adap->dev->desc->name,
+                       adap->dev->owner, &adap->dev->udev->dev)) < 0) {
                deb_info("dvb_register_adapter failed: error %d", ret);
                goto err;
        }
-       d->dvb_adap.priv = d;
-
-       if (d->props.read_mac_address) {
-               if (d->props.read_mac_address(d,d->dvb_adap.proposed_mac) == 0)
-                       info("MAC address: %02x:%02x:%02x:%02x:%02x:%02x",d->dvb_adap.proposed_mac[0],
-                                       d->dvb_adap.proposed_mac[1],d->dvb_adap.proposed_mac[2],
-                                       d->dvb_adap.proposed_mac[3],d->dvb_adap.proposed_mac[4],
-                                       d->dvb_adap.proposed_mac[5]);
+       adap->dvb_adap.priv = adap;
+
+       if (adap->dev->props.read_mac_address) {
+               if (adap->dev->props.read_mac_address(adap->dev,adap->dvb_adap.proposed_mac) == 0)
+                       info("MAC address: %02x:%02x:%02x:%02x:%02x:%02x",adap->dvb_adap.proposed_mac[0],
+                                       adap->dvb_adap.proposed_mac[1], adap->dvb_adap.proposed_mac[2],
+                                       adap->dvb_adap.proposed_mac[3], adap->dvb_adap.proposed_mac[4],
+                                       adap->dvb_adap.proposed_mac[5]);
                else
                        err("MAC address reading failed.");
        }
 
 
-       d->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
-       d->demux.priv = d;
+       adap->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
+       adap->demux.priv             = adap;
 
-       d->demux.feednum = d->demux.filternum = d->max_feed_count;
-       d->demux.start_feed = dvb_usb_start_feed;
-       d->demux.stop_feed  = dvb_usb_stop_feed;
-       d->demux.write_to_decoder = NULL;
-       if ((ret = dvb_dmx_init(&d->demux)) < 0) {
+       adap->demux.feednum          = adap->demux.filternum = adap->max_feed_count;
+       adap->demux.start_feed       = dvb_usb_start_feed;
+       adap->demux.stop_feed        = dvb_usb_stop_feed;
+       adap->demux.write_to_decoder = NULL;
+       if ((ret = dvb_dmx_init(&adap->demux)) < 0) {
                err("dvb_dmx_init failed: error %d",ret);
                goto err_dmx;
        }
 
-       d->dmxdev.filternum = d->demux.filternum;
-       d->dmxdev.demux = &d->demux.dmx;
-       d->dmxdev.capabilities = 0;
-       if ((ret = dvb_dmxdev_init(&d->dmxdev, &d->dvb_adap)) < 0) {
+       adap->dmxdev.filternum       = adap->demux.filternum;
+       adap->dmxdev.demux           = &adap->demux.dmx;
+       adap->dmxdev.capabilities    = 0;
+       if ((ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap)) < 0) {
                err("dvb_dmxdev_init failed: error %d",ret);
                goto err_dmx_dev;
        }
 
-       dvb_net_init(&d->dvb_adap, &d->dvb_net, &d->demux.dmx);
+       dvb_net_init(&adap->dvb_adap, &adap->dvb_net, &adap->demux.dmx);
 
-       d->state |= DVB_USB_STATE_DVB;
+       adap->state |= DVB_USB_ADAP_STATE_DVB;
        return 0;
 
 err_dmx_dev:
-       dvb_dmx_release(&d->demux);
+       dvb_dmx_release(&adap->demux);
 err_dmx:
-       dvb_unregister_adapter(&d->dvb_adap);
+       dvb_unregister_adapter(&adap->dvb_adap);
 err:
        return ret;
 }
 
-int dvb_usb_dvb_exit(struct dvb_usb_device *d)
+int dvb_usb_adapter_dvb_exit(struct dvb_usb_adapter *adap)
 {
-       if (d->state & DVB_USB_STATE_DVB) {
+       if (adap->state & DVB_USB_ADAP_STATE_DVB) {
                deb_info("unregistering DVB part\n");
-               dvb_net_release(&d->dvb_net);
-               d->demux.dmx.close(&d->demux.dmx);
-               dvb_dmxdev_release(&d->dmxdev);
-               dvb_dmx_release(&d->demux);
-               dvb_unregister_adapter(&d->dvb_adap);
-               d->state &= ~DVB_USB_STATE_DVB;
+               dvb_net_release(&adap->dvb_net);
+               adap->demux.dmx.close(&adap->demux.dmx);
+               dvb_dmxdev_release(&adap->dmxdev);
+               dvb_dmx_release(&adap->demux);
+               dvb_unregister_adapter(&adap->dvb_adap);
+               adap->state &= ~DVB_USB_ADAP_STATE_DVB;
        }
        return 0;
 }
 
 static int dvb_usb_fe_wakeup(struct dvb_frontend *fe)
 {
-       struct dvb_usb_device *d = fe->dvb->priv;
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
 
-       if (d->props.power_ctrl)
-               d->props.power_ctrl(d,1);
+       dvb_usb_device_power_ctrl(adap->dev, 1);
 
-       if (d->fe_init)
-               d->fe_init(fe);
+       if (adap->fe_init)
+               adap->fe_init(fe);
 
        return 0;
 }
 
 static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
 {
-       struct dvb_usb_device *d = fe->dvb->priv;
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
 
-       if (d->fe_sleep)
-               d->fe_sleep(fe);
+       if (adap->fe_sleep)
+               adap->fe_sleep(fe);
 
-       if (d->props.power_ctrl)
-               d->props.power_ctrl(d,0);
-
-       return 0;
+       return dvb_usb_device_power_ctrl(adap->dev, 0);
 }
 
-int dvb_usb_fe_init(struct dvb_usb_device* d)
+int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap)
 {
-       if (d->props.frontend_attach == NULL) {
-               err("strange: '%s' doesn't want to attach a frontend.",d->desc->name);
+       if (adap->props.frontend_attach == NULL) {
+               err("strange: '%s' #%d doesn't want to attach a frontend.",adap->dev->desc->name, adap->id);
                return 0;
        }
 
        /* re-assign sleep and wakeup functions */
-       if (d->props.frontend_attach(d) == 0 && d->fe != NULL) {
-               d->fe_init = d->fe->ops.init;   d->fe->ops.init  = dvb_usb_fe_wakeup;
-               d->fe_sleep = d->fe->ops.sleep; d->fe->ops.sleep = dvb_usb_fe_sleep;
+       if (adap->props.frontend_attach(adap) == 0 && adap->fe != NULL) {
+               adap->fe_init  = adap->fe->ops.init;  adap->fe->ops.init  = dvb_usb_fe_wakeup;
+               adap->fe_sleep = adap->fe->ops.sleep; adap->fe->ops.sleep = dvb_usb_fe_sleep;
 
-               if (dvb_register_frontend(&d->dvb_adap, d->fe)) {
+               if (dvb_register_frontend(&adap->dvb_adap, adap->fe)) {
                        err("Frontend registration failed.");
-                       dvb_frontend_detach(d->fe);
-                       d->fe = NULL;
+                       dvb_frontend_detach(adap->fe);
+                       adap->fe = NULL;
                        return -ENODEV;
                }
 
                /* only attach the tuner if the demod is there */
-               if (d->props.tuner_attach != NULL)
-                       d->props.tuner_attach(d);
+               if (adap->props.tuner_attach != NULL)
+                       adap->props.tuner_attach(adap);
        } else
-               err("no frontend was attached by '%s'",d->desc->name);
+               err("no frontend was attached by '%s'",adap->dev->desc->name);
 
        return 0;
 }
 
-int dvb_usb_fe_exit(struct dvb_usb_device *d)
+int dvb_usb_adapter_frontend_exit(struct dvb_usb_adapter *adap)
 {
-       if (d->fe != NULL) {
-               dvb_unregister_frontend(d->fe);
-               dvb_frontend_detach(d->fe);
+       if (adap->fe != NULL) {
+               dvb_unregister_frontend(adap->fe);
+               dvb_frontend_detach(adap->fe);
        }
        return 0;
 }
index 9222b0a81f748646f82eda2ec382e16af1d2db7d..e1112e39fb638e4d9731510afd7a22667ba434ea 100644 (file)
@@ -1,6 +1,6 @@
 /* dvb-usb-firmware.c is part of the DVB USB library.
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
  * see dvb-usb-init.c for copyright information.
  *
  * This file contains functions for downloading the firmware to Cypress FX 1 and 2 based devices.
@@ -24,9 +24,6 @@ static struct usb_cypress_controller cypress[] = {
        { .id = CYPRESS_FX2,     .name = "Cypress FX2",     .cpu_cs_register = 0xe600 },
 };
 
-static int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx,
-                              int *pos);
-
 /*
  * load a firmware packet to the device
  */
@@ -78,7 +75,7 @@ int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw
 }
 EXPORT_SYMBOL(usb_cypress_load_firmware);
 
-int dvb_usb_download_firmware(struct usb_device *udev, struct dvb_usb_properties *props)
+int dvb_usb_download_firmware(struct usb_device *udev, struct dvb_usb_device_properties *props)
 {
        int ret;
        const struct firmware *fw = NULL;
@@ -115,7 +112,7 @@ int dvb_usb_download_firmware(struct usb_device *udev, struct dvb_usb_properties
        return ret;
 }
 
-static int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx,
+int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx,
                               int *pos)
 {
        u8 *b = (u8 *) &fw->data[*pos];
@@ -146,3 +143,4 @@ static int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx,
 
        return *pos;
 }
+EXPORT_SYMBOL(dvb_usb_get_hexline);
index 6b611a72509309d4c4eefd84f513687df785ee5e..55ba020386c97d32db99f288250c5d603a382789 100644 (file)
@@ -1,6 +1,6 @@
 /* dvb-usb-i2c.c is part of the DVB USB library.
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
  * see dvb-usb-init.c for copyright information.
  *
  * This file contains functions for (de-)initializing an I2C adapter.
@@ -48,48 +48,48 @@ int dvb_usb_i2c_exit(struct dvb_usb_device *d)
 
 int dvb_usb_tuner_init_i2c(struct dvb_frontend *fe)
 {
-       struct dvb_usb_device *d = fe->dvb->priv;
-       struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = d->pll_init, .len = 4 };
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+       struct i2c_msg msg = { .addr = adap->pll_addr, .flags = 0, .buf = adap->pll_init, .len = 4 };
        int ret = 0;
 
        /* if pll_desc is not used */
-       if (d->pll_desc == NULL)
+       if (adap->pll_desc == NULL)
                return 0;
 
-       if (d->tuner_pass_ctrl)
-               d->tuner_pass_ctrl(fe,1,d->pll_addr);
+       if (adap->tuner_pass_ctrl)
+               adap->tuner_pass_ctrl(fe, 1, adap->pll_addr);
 
-       deb_pll("pll init: %x\n",d->pll_addr);
-       deb_pll("pll-buf: %x %x %x %x\n",d->pll_init[0],d->pll_init[1],
-                       d->pll_init[2],d->pll_init[3]);
+       deb_pll("pll init: %x\n",adap->pll_addr);
+       deb_pll("pll-buf: %x %x %x %x\n",adap->pll_init[0], adap->pll_init[1],
+                       adap->pll_init[2], adap->pll_init[3]);
 
        if (fe->ops.i2c_gate_ctrl)
                fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) {
+       if (i2c_transfer (&adap->dev->i2c_adap, &msg, 1) != 1) {
                err("tuner i2c write failed for pll_init.");
                ret = -EREMOTEIO;
        }
        msleep(1);
 
-       if (d->tuner_pass_ctrl)
-               d->tuner_pass_ctrl(fe,0,d->pll_addr);
+       if (adap->tuner_pass_ctrl)
+               adap->tuner_pass_ctrl(fe,0,adap->pll_addr);
        return ret;
 }
 EXPORT_SYMBOL(dvb_usb_tuner_init_i2c);
 
 int dvb_usb_tuner_calc_regs(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep, u8 *b, int buf_len)
 {
-       struct dvb_usb_device *d = fe->dvb->priv;
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
 
        if (buf_len != 5)
                return -EINVAL;
-       if (d->pll_desc == NULL)
+       if (adap->pll_desc == NULL)
                return 0;
 
-       deb_pll("pll addr: %x, freq: %d %p\n",d->pll_addr,fep->frequency,d->pll_desc);
+       deb_pll("pll addr: %x, freq: %d %p\n",adap->pll_addr, fep->frequency, adap->pll_desc);
 
-       b[0] = d->pll_addr;
-       dvb_pll_configure(d->pll_desc,&b[1],fep->frequency,fep->u.ofdm.bandwidth);
+       b[0] = adap->pll_addr;
+       dvb_pll_configure(adap->pll_desc, &b[1], fep->frequency, fep->u.ofdm.bandwidth);
 
        deb_pll("pll-buf: %x %x %x %x %x\n",b[0],b[1],b[2],b[3],b[4]);
 
@@ -99,26 +99,27 @@ EXPORT_SYMBOL(dvb_usb_tuner_calc_regs);
 
 int dvb_usb_tuner_set_params_i2c(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
 {
-       struct dvb_usb_device *d = fe->dvb->priv;
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
        int ret = 0;
        u8 b[5];
-       struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = &b[1], .len = 4 };
+       struct i2c_msg msg = { .addr = adap->pll_addr, .flags = 0, .buf = &b[1], .len = 4 };
 
        dvb_usb_tuner_calc_regs(fe,fep,b,5);
 
-       if (d->tuner_pass_ctrl)
-               d->tuner_pass_ctrl(fe,1,d->pll_addr);
+       if (adap->tuner_pass_ctrl)
+               adap->tuner_pass_ctrl(fe, 1, adap->pll_addr);
 
        if (fe->ops.i2c_gate_ctrl)
                fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) {
+
+       if (i2c_transfer(&adap->dev->i2c_adap, &msg, 1) != 1) {
                err("tuner i2c write failed for pll_set.");
                ret = -EREMOTEIO;
        }
        msleep(1);
 
-       if (d->tuner_pass_ctrl)
-               d->tuner_pass_ctrl(fe,0,d->pll_addr);
+       if (adap->tuner_pass_ctrl)
+               adap->tuner_pass_ctrl(fe, 0, adap->pll_addr);
 
        return ret;
 }
index 57a10de1d3dd113c986fd858d7b07d7707e72713..4d6b069536ce387575dacf11278f1d73c61862f9 100644 (file)
@@ -52,8 +52,7 @@
 #define USB_PID_DIBCOM_MOD3000_WARM                    0x0bb9
 #define USB_PID_DIBCOM_MOD3001_COLD                    0x0bc6
 #define USB_PID_DIBCOM_MOD3001_WARM                    0x0bc7
-#define USB_PID_DIBCOM_STK7700                         0x1e14
-#define USB_PID_DIBCOM_STK7700_REENUM                  0x1e15
+#define USB_PID_DIBCOM_STK7700P                                0x1e14
 #define USB_PID_DIBCOM_ANCHOR_2135_COLD                        0x2131
 #define USB_PID_GRANDTEC_DVBT_USB_COLD                 0x0fa0
 #define USB_PID_GRANDTEC_DVBT_USB_WARM                 0x0fa1
 #define USB_PID_WT220U_ZL0353_WARM                     0x022b
 #define USB_PID_WINTV_NOVA_T_USB2_COLD                 0x9300
 #define USB_PID_WINTV_NOVA_T_USB2_WARM                 0x9301
+#define USB_PID_HAUPPAUGE_NOVA_T_500                   0x9941
+#define USB_PID_HAUPPAUGE_NOVA_T_500_2                 0x9950
+#define USB_PID_HAUPPAUGE_NOVA_T_STICK                 0x7050
+#define USB_PID_AVERMEDIA_VOLAR                                0x1234
 #define USB_PID_NEBULA_DIGITV                          0x0201
 #define USB_PID_DVICO_BLUEBIRD_LGDT                    0xd820
 #define USB_PID_DVICO_BLUEBIRD_LG064F_COLD             0xd500
 #define USB_PID_DVICO_BLUEBIRD_LGZ201_WARM             0xdb01
 #define USB_PID_DVICO_BLUEBIRD_TH7579_COLD             0xdb10
 #define USB_PID_DVICO_BLUEBIRD_TH7579_WARM             0xdb11
-#define USB_PID_DVICO_BLUEBIRD_DEE1601_COLD            0xdb50
-#define USB_PID_DVICO_BLUEBIRD_DEE1601_WARM            0xdb51
-#define USB_PID_DIGITALNOW_BLUEBIRD_DEE1601_COLD       0xdb54
-#define USB_PID_DIGITALNOW_BLUEBIRD_DEE1601_WARM       0xdb55
+#define USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD             0xdb50
+#define USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM             0xdb51
+#define USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD             0xdb58
+#define USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM             0xdb59
+#define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD        0xdb54
+#define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM        0xdb55
 #define USB_PID_MEDION_MD95700                         0x0932
 #define USB_PID_KYE_DVB_T_COLD                         0x701e
 #define USB_PID_KYE_DVB_T_WARM                         0x701f
index a1705ecb9a544ac8c99872daa9f658a0f4051815..ffdde83d1e77be6be34e5068f9a1b34adbdcd5e6 100644 (file)
@@ -3,7 +3,7 @@
  *
  * dvb-usb-init.c
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
  *
  *     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
 /* debug */
 int dvb_usb_debug;
 module_param_named(debug,dvb_usb_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64 (or-able))." DVB_USB_DEBUG_STATUS);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64,mem=128,uxfer=256  (or-able))." DVB_USB_DEBUG_STATUS);
 
 int dvb_usb_disable_rc_polling;
 module_param_named(disable_rc_polling, dvb_usb_disable_rc_polling, int, 0644);
 MODULE_PARM_DESC(disable_rc_polling, "disable remote control polling (default: 0).");
 
+static int dvb_usb_force_pid_filter_usage;
+module_param_named(force_pid_filter_usage, dvb_usb_force_pid_filter_usage, int, 0444);
+MODULE_PARM_DESC(disable_rc_polling, "force all dvb-usb-devices to use a PID filter, if any (default: 0).");
+
+static int dvb_usb_adapter_init(struct dvb_usb_device *d)
+{
+       struct dvb_usb_adapter *adap;
+       int ret,n;
+
+       for (n = 0; n < d->props.num_adapters; n++) {
+               adap = &d->adapter[n];
+               adap->dev = d;
+               adap->id  = n;
+
+               memcpy(&adap->props, &d->props.adapter[n], sizeof(struct dvb_usb_adapter_properties));
+
+/* speed - when running at FULL speed we need a HW PID filter */
+               if (d->udev->speed == USB_SPEED_FULL && !(adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER)) {
+                       err("This USB2.0 device cannot be run on a USB1.1 port. (it lacks a hardware PID filter)");
+                       return -ENODEV;
+               }
+
+               if ((d->udev->speed == USB_SPEED_FULL && adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER) ||
+                       (adap->props.caps & DVB_USB_ADAP_NEED_PID_FILTERING)) {
+                       info("will use the device's hardware PID filter (table count: %d).",adap->props.pid_filter_count);
+                       adap->pid_filtering  = 1;
+                       adap->max_feed_count = adap->props.pid_filter_count;
+               } else {
+                       info("will pass the complete MPEG2 transport stream to the software demuxer.");
+                       adap->pid_filtering  = 0;
+                       adap->max_feed_count = 255;
+               }
+
+               if (!adap->pid_filtering &&
+                       dvb_usb_force_pid_filter_usage &&
+                       adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER) {
+                       info("pid filter enabled by module option.");
+                       adap->pid_filtering  = 1;
+                       adap->max_feed_count = adap->props.pid_filter_count;
+               }
+
+               if (adap->props.size_of_priv > 0) {
+                       adap->priv = kzalloc(adap->props.size_of_priv,GFP_KERNEL);
+                       if (adap->priv == NULL) {
+                               err("no memory for priv for adapter %d.",n);
+                               return -ENOMEM;
+                       }
+               }
+
+               if ((ret = dvb_usb_adapter_stream_init(adap)) ||
+                       (ret = dvb_usb_adapter_dvb_init(adap)) ||
+                       (ret = dvb_usb_adapter_frontend_init(adap))) {
+                       return ret;
+               }
+
+               d->num_adapters_initialized++;
+               d->state |= DVB_USB_STATE_DVB;
+       }
+
+       /*
+        * when reloading the driver w/o replugging the device
+        * sometimes a timeout occures, this helps
+        */
+       if (d->props.generic_bulk_ctrl_endpoint != 0) {
+               usb_clear_halt(d->udev,usb_sndbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint));
+               usb_clear_halt(d->udev,usb_rcvbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint));
+       }
+
+       return 0;
+}
+
+static int dvb_usb_adapter_exit(struct dvb_usb_device *d)
+{
+       int n;
+       for (n = 0; n < d->num_adapters_initialized; n++) {
+               dvb_usb_adapter_frontend_exit(&d->adapter[n]);
+               dvb_usb_adapter_dvb_exit(&d->adapter[n]);
+               dvb_usb_adapter_stream_exit(&d->adapter[n]);
+               kfree(d->adapter[n].priv);
+       }
+       d->num_adapters_initialized = 0;
+       d->state &= ~DVB_USB_STATE_DVB;
+       return 0;
+}
+
+
 /* general initialization functions */
 static int dvb_usb_exit(struct dvb_usb_device *d)
 {
        deb_info("state before exiting everything: %x\n",d->state);
        dvb_usb_remote_exit(d);
-       dvb_usb_fe_exit(d);
+       dvb_usb_adapter_exit(d);
        dvb_usb_i2c_exit(d);
-       dvb_usb_dvb_exit(d);
-       dvb_usb_urb_exit(d);
        deb_info("state should be zero now: %x\n",d->state);
        d->state = DVB_USB_STATE_INIT;
        kfree(d->priv);
@@ -47,32 +131,19 @@ static int dvb_usb_init(struct dvb_usb_device *d)
 
        d->state = DVB_USB_STATE_INIT;
 
-/* check the capabilities and set appropriate variables */
-
-/* speed - when running at FULL speed we need a HW PID filter */
-       if (d->udev->speed == USB_SPEED_FULL && !(d->props.caps & DVB_USB_HAS_PID_FILTER)) {
-               err("This USB2.0 device cannot be run on a USB1.1 port. (it lacks a hardware PID filter)");
-               return -ENODEV;
-       }
-
-       if ((d->udev->speed == USB_SPEED_FULL && d->props.caps & DVB_USB_HAS_PID_FILTER) ||
-               (d->props.caps & DVB_USB_NEED_PID_FILTERING)) {
-               info("will use the device's hardware PID filter (table count: %d).",d->props.pid_filter_count);
-               d->pid_filtering = 1;
-               d->max_feed_count = d->props.pid_filter_count;
-       } else {
-               info("will pass the complete MPEG2 transport stream to the software demuxer.");
-               d->pid_filtering = 0;
-               d->max_feed_count = 255;
+       if (d->props.size_of_priv > 0) {
+               d->priv = kzalloc(d->props.size_of_priv,GFP_KERNEL);
+               if (d->priv == NULL) {
+                       err("no memory for priv in 'struct dvb_usb_device'");
+                       return -ENOMEM;
+               }
        }
 
-       if (d->props.power_ctrl)
-               d->props.power_ctrl(d,1);
+/* check the capabilities and set appropriate variables */
+       dvb_usb_device_power_ctrl(d, 1);
 
-       if ((ret = dvb_usb_urb_init(d)) ||
-               (ret = dvb_usb_dvb_init(d)) ||
-               (ret = dvb_usb_i2c_init(d)) ||
-               (ret = dvb_usb_fe_init(d))) {
+       if ((ret = dvb_usb_i2c_init(d)) ||
+               (ret = dvb_usb_adapter_init(d))) {
                dvb_usb_exit(d);
                return ret;
        }
@@ -80,14 +151,13 @@ static int dvb_usb_init(struct dvb_usb_device *d)
        if ((ret = dvb_usb_remote_init(d)))
                err("could not initialize remote control.");
 
-       if (d->props.power_ctrl)
-               d->props.power_ctrl(d,0);
+       dvb_usb_device_power_ctrl(d, 0);
 
        return 0;
 }
 
 /* determine the name and the state of the just found USB device */
-static struct dvb_usb_device_description * dvb_usb_find_device(struct usb_device *udev,struct dvb_usb_properties *props, int *cold)
+static struct dvb_usb_device_description * dvb_usb_find_device(struct usb_device *udev,struct dvb_usb_device_properties *props, int *cold)
 {
        int i,j;
        struct dvb_usb_device_description *desc = NULL;
@@ -125,11 +195,25 @@ static struct dvb_usb_device_description * dvb_usb_find_device(struct usb_device
        return desc;
 }
 
+int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       if (onoff)
+               d->powered++;
+       else
+               d->powered--;
+
+       if (d->powered == 0 || (onoff && d->powered == 1)) { // when switching from 1 to 0 or from 0 to 1
+               deb_info("power control: %d\n", onoff);
+               if (d->props.power_ctrl)
+                       return d->props.power_ctrl(d, onoff);
+       }
+       return 0;
+}
+
 /*
  * USB
  */
-
-int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties
+int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_device_properties
                *props, struct module *owner,struct dvb_usb_device **du)
 {
        struct usb_device *udev = interface_to_usbdev(intf);
@@ -149,7 +233,7 @@ int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties
        if (cold) {
                info("found a '%s' in cold state, will try to load a firmware",desc->name);
                ret = dvb_usb_download_firmware(udev,props);
-               if (!props->no_reconnect)
+               if (!props->no_reconnect || ret != 0)
                        return ret;
        }
 
@@ -161,19 +245,10 @@ int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties
        }
 
        d->udev = udev;
-       memcpy(&d->props,props,sizeof(struct dvb_usb_properties));
+       memcpy(&d->props,props,sizeof(struct dvb_usb_device_properties));
        d->desc = desc;
        d->owner = owner;
 
-       if (d->props.size_of_priv > 0) {
-                       d->priv = kzalloc(d->props.size_of_priv,GFP_KERNEL);
-               if (d->priv == NULL) {
-                       err("no memory for priv in 'struct dvb_usb_device'");
-                       kfree(d);
-                       return -ENOMEM;
-               }
-       }
-
        usb_set_intfdata(intf, d);
 
        if (du != NULL)
@@ -204,7 +279,7 @@ void dvb_usb_device_exit(struct usb_interface *intf)
 }
 EXPORT_SYMBOL(dvb_usb_device_exit);
 
-MODULE_VERSION("0.3");
+MODULE_VERSION("1.0");
 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
 MODULE_DESCRIPTION("A library module containing commonly used USB and DVB function USB DVB devices");
 MODULE_LICENSE("GPL");
index 380b2a45ee4c2accc59d0b8af0da13e6dc980dc5..0a3a0b6c23509f8e80c95dae37d595bbd516d50e 100644 (file)
@@ -1,6 +1,6 @@
 /* dvb-usb-remote.c is part of the DVB USB library.
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
  * see dvb-usb-init.c for copyright information.
  *
  * This file contains functions for initializing the the input-device and for handling remote-control-queries.
index 88b283731bb8c84e1dcf7c4a90cc15b0604fd1c6..5cef12a07f72d8beae5757fe9b7596b7406721ad 100644 (file)
@@ -1,9 +1,9 @@
 /* dvb-usb-urb.c is part of the DVB USB library.
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
  * see dvb-usb-init.c for copyright information.
  *
- * This file contains functions for initializing and handling the
+ * This file keeps functions for initializing and handling the
  * USB and URB stuff.
  */
 #include "dvb-usb-common.h"
@@ -64,260 +64,32 @@ int dvb_usb_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len)
 }
 EXPORT_SYMBOL(dvb_usb_generic_write);
 
-
-/* URB stuff for streaming */
-static void dvb_usb_urb_complete(struct urb *urb, struct pt_regs *ptregs)
-{
-       struct dvb_usb_device *d = urb->context;
-       int ptype = usb_pipetype(urb->pipe);
-       int i;
-       u8 *b;
-
-       deb_ts("'%s' urb completed. feedcount: %d, status: %d, length: %d/%d, pack_num: %d, errors: %d\n",
-                       ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk", d->feedcount,
-                       urb->status,urb->actual_length,urb->transfer_buffer_length,
-                       urb->number_of_packets,urb->error_count);
-
-       switch (urb->status) {
-               case 0:         /* success */
-                       break;
-               case -ECONNRESET:   /* kill */
-               case -ENOENT:
-               case -ESHUTDOWN:
-                       return;
-               default:        /* error */
-                       deb_ts("urb completition error %d.", urb->status);
-                       break;
-       }
-
-       if (d->feedcount > 0) {
-               if (d->state & DVB_USB_STATE_DVB) {
-                       switch (ptype) {
-                               case PIPE_ISOCHRONOUS:
-                                       b = (u8 *) urb->transfer_buffer;
-                                       for (i = 0; i < urb->number_of_packets; i++) {
-                                               if (urb->iso_frame_desc[i].status != 0)
-                                                       deb_ts("iso frame descriptor has an error: %d\n",urb->iso_frame_desc[i].status);
-                                               else if (urb->iso_frame_desc[i].actual_length > 0) {
-                                                               dvb_dmx_swfilter(&d->demux,b + urb->iso_frame_desc[i].offset,
-                                                                               urb->iso_frame_desc[i].actual_length);
-                                                       }
-                                               urb->iso_frame_desc[i].status = 0;
-                                               urb->iso_frame_desc[i].actual_length = 0;
-                                       }
-                                       debug_dump(b,20,deb_ts);
-                                       break;
-                               case PIPE_BULK:
-                                       if (urb->actual_length > 0)
-                                               dvb_dmx_swfilter(&d->demux, (u8 *) urb->transfer_buffer,urb->actual_length);
-                                       break;
-                               default:
-                                       err("unkown endpoint type in completition handler.");
-                                       return;
-                       }
-               }
-       }
-
-       usb_submit_urb(urb,GFP_ATOMIC);
-}
-
-int dvb_usb_urb_kill(struct dvb_usb_device *d)
-{
-       int i;
-       for (i = 0; i < d->urbs_submitted; i++) {
-               deb_ts("killing URB no. %d.\n",i);
-
-               /* stop the URB */
-               usb_kill_urb(d->urb_list[i]);
-       }
-       d->urbs_submitted = 0;
-       return 0;
-}
-
-int dvb_usb_urb_submit(struct dvb_usb_device *d)
-{
-       int i,ret;
-       for (i = 0; i < d->urbs_initialized; i++) {
-               deb_ts("submitting URB no. %d\n",i);
-               if ((ret = usb_submit_urb(d->urb_list[i],GFP_ATOMIC))) {
-                       err("could not submit URB no. %d - get them all back",i);
-                       dvb_usb_urb_kill(d);
-                       return ret;
-               }
-               d->urbs_submitted++;
-       }
-       return 0;
-}
-
-static int dvb_usb_free_stream_buffers(struct dvb_usb_device *d)
-{
-       if (d->state & DVB_USB_STATE_URB_BUF) {
-               while (d->buf_num) {
-                       d->buf_num--;
-                       deb_mem("freeing buffer %d\n",d->buf_num);
-                       usb_buffer_free(d->udev, d->buf_size,
-                                       d->buf_list[d->buf_num], d->dma_addr[d->buf_num]);
-               }
-               kfree(d->buf_list);
-               kfree(d->dma_addr);
-       }
-
-       d->state &= ~DVB_USB_STATE_URB_BUF;
-
-       return 0;
-}
-
-static int dvb_usb_allocate_stream_buffers(struct dvb_usb_device *d, int num, unsigned long size)
-{
-       d->buf_num = 0;
-       d->buf_size = size;
-
-       deb_mem("all in all I will use %lu bytes for streaming\n",num*size);
-
-       if ((d->buf_list = kcalloc(num, sizeof(u8 *), GFP_ATOMIC)) == NULL)
-               return -ENOMEM;
-
-       if ((d->dma_addr = kcalloc(num, sizeof(dma_addr_t), GFP_ATOMIC)) == NULL) {
-               kfree(d->buf_list);
-               return -ENOMEM;
-       }
-
-       d->state |= DVB_USB_STATE_URB_BUF;
-
-       for (d->buf_num = 0; d->buf_num < num; d->buf_num++) {
-               deb_mem("allocating buffer %d\n",d->buf_num);
-               if (( d->buf_list[d->buf_num] =
-                                       usb_buffer_alloc(d->udev, size, SLAB_ATOMIC,
-                                       &d->dma_addr[d->buf_num]) ) == NULL) {
-                       deb_mem("not enough memory for urb-buffer allocation.\n");
-                       dvb_usb_free_stream_buffers(d);
-                       return -ENOMEM;
-               }
-               deb_mem("buffer %d: %p (dma: %llu)\n",
-                       d->buf_num, d->buf_list[d->buf_num],
-                       (unsigned long long)d->dma_addr[d->buf_num]);
-               memset(d->buf_list[d->buf_num],0,size);
-       }
-       deb_mem("allocation successful\n");
-
-       return 0;
-}
-
-static int dvb_usb_bulk_urb_init(struct dvb_usb_device *d)
+static void dvb_usb_data_complete(struct usb_data_stream *stream, u8 *buffer, size_t length)
 {
-       int i;
-
-       if ((i = dvb_usb_allocate_stream_buffers(d,d->props.urb.count,
-                                       d->props.urb.u.bulk.buffersize)) < 0)
-               return i;
-
-       /* allocate the URBs */
-       for (i = 0; i < d->props.urb.count; i++) {
-               if ((d->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC)) == NULL)
-                       return -ENOMEM;
-
-               usb_fill_bulk_urb( d->urb_list[i], d->udev,
-                               usb_rcvbulkpipe(d->udev,d->props.urb.endpoint),
-                               d->buf_list[i],
-                               d->props.urb.u.bulk.buffersize,
-                               dvb_usb_urb_complete, d);
-
-               d->urb_list[i]->transfer_flags = 0;
-               d->urbs_initialized++;
-       }
-       return 0;
+       struct dvb_usb_adapter *adap = stream->user_priv;
+       if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB)
+               dvb_dmx_swfilter(&adap->demux, buffer, length);
 }
 
-static int dvb_usb_isoc_urb_init(struct dvb_usb_device *d)
+static void dvb_usb_data_complete_204(struct usb_data_stream *stream, u8 *buffer, size_t length)
 {
-       int i,j;
-
-       if ((i = dvb_usb_allocate_stream_buffers(d,d->props.urb.count,
-                                       d->props.urb.u.isoc.framesize*d->props.urb.u.isoc.framesperurb)) < 0)
-               return i;
-
-       /* allocate the URBs */
-       for (i = 0; i < d->props.urb.count; i++) {
-               struct urb *urb;
-               int frame_offset = 0;
-               if ((d->urb_list[i] =
-                                       usb_alloc_urb(d->props.urb.u.isoc.framesperurb,GFP_ATOMIC)) == NULL)
-                       return -ENOMEM;
-
-               urb = d->urb_list[i];
-
-               urb->dev = d->udev;
-               urb->context = d;
-               urb->complete = dvb_usb_urb_complete;
-               urb->pipe = usb_rcvisocpipe(d->udev,d->props.urb.endpoint);
-               urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
-               urb->interval = d->props.urb.u.isoc.interval;
-               urb->number_of_packets = d->props.urb.u.isoc.framesperurb;
-               urb->transfer_buffer_length = d->buf_size;
-               urb->transfer_buffer = d->buf_list[i];
-               urb->transfer_dma = d->dma_addr[i];
-
-               for (j = 0; j < d->props.urb.u.isoc.framesperurb; j++) {
-                       urb->iso_frame_desc[j].offset = frame_offset;
-                       urb->iso_frame_desc[j].length = d->props.urb.u.isoc.framesize;
-                       frame_offset += d->props.urb.u.isoc.framesize;
-               }
-
-               d->urbs_initialized++;
-       }
-       return 0;
-
+       struct dvb_usb_adapter *adap = stream->user_priv;
+       if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB)
+               dvb_dmx_swfilter_204(&adap->demux, buffer, length);
 }
 
-int dvb_usb_urb_init(struct dvb_usb_device *d)
+int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap)
 {
-       /*
-        * when reloading the driver w/o replugging the device
-        * sometimes a timeout occures, this helps
-        */
-       if (d->props.generic_bulk_ctrl_endpoint != 0) {
-               usb_clear_halt(d->udev,usb_sndbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint));
-               usb_clear_halt(d->udev,usb_rcvbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint));
-       }
-       usb_clear_halt(d->udev,usb_rcvbulkpipe(d->udev,d->props.urb.endpoint));
-
-       /* allocate the array for the data transfer URBs */
-       d->urb_list = kzalloc(d->props.urb.count * sizeof(struct urb *),GFP_KERNEL);
-       if (d->urb_list == NULL)
-               return -ENOMEM;
-       d->state |= DVB_USB_STATE_URB_LIST;
-
-       switch (d->props.urb.type) {
-               case DVB_USB_BULK:
-                       return dvb_usb_bulk_urb_init(d);
-               case DVB_USB_ISOC:
-                       return dvb_usb_isoc_urb_init(d);
-               default:
-                       err("unkown URB-type for data transfer.");
-                       return -EINVAL;
-       }
+       adap->stream.udev      = adap->dev->udev;
+       if (adap->props.caps & DVB_USB_ADAP_RECEIVES_204_BYTE_TS)
+               adap->stream.complete = dvb_usb_data_complete_204;
+       else
+       adap->stream.complete  = dvb_usb_data_complete;
+       adap->stream.user_priv = adap;
+       return usb_urb_init(&adap->stream, &adap->props.stream);
 }
 
-int dvb_usb_urb_exit(struct dvb_usb_device *d)
+int dvb_usb_adapter_stream_exit(struct dvb_usb_adapter *adap)
 {
-       int i;
-
-       dvb_usb_urb_kill(d);
-
-       if (d->state & DVB_USB_STATE_URB_LIST) {
-               for (i = 0; i < d->urbs_initialized; i++) {
-                       if (d->urb_list[i] != NULL) {
-                               deb_mem("freeing URB no. %d.\n",i);
-                               /* free the URBs */
-                               usb_free_urb(d->urb_list[i]);
-                       }
-               }
-               d->urbs_initialized = 0;
-               /* free the urb array */
-               kfree(d->urb_list);
-               d->state &= ~DVB_USB_STATE_URB_LIST;
-       }
-
-       dvb_usb_free_stream_buffers(d);
-       return 0;
+       return usb_urb_exit(&adap->stream);
 }
index 97f8ea9624385ae828834209bcf2ee872ab2e66f..376c45a8e77991712260386717a22c12757930a6 100644 (file)
@@ -1,9 +1,11 @@
 /* dvb-usb.h is part of the DVB USB library.
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
  * see dvb-usb-init.c for copyright information.
  *
  * the headerfile, all dvb-usb-drivers have to include.
+ *
+ * TODO: clean-up the structures for unused fields and update the comments
  */
 #ifndef __DVB_USB_H__
 #define __DVB_USB_H__
@@ -84,36 +86,84 @@ struct dvb_usb_rc_key {
 };
 
 struct dvb_usb_device;
+struct dvb_usb_adapter;
+struct usb_data_stream;
+
+/**
+ * Properties of USB streaming - TODO this structure should be somewhere else
+ * describes the kind of USB transfer used for data-streaming.
+ *  (BULK or ISOC)
+ */
+struct usb_data_stream_properties {
+#define USB_BULK  1
+#define USB_ISOC  2
+       int type;
+       int count;
+       int endpoint;
+
+       union {
+               struct {
+                       int buffersize; /* per URB */
+               } bulk;
+               struct {
+                       int framesperurb;
+                       int framesize;
+                       int interval;
+               } isoc;
+       } u;
+};
 
 /**
- * struct dvb_usb_properties - properties of a dvb-usb-device
+ * struct dvb_usb_adapter_properties - properties of a dvb-usb-adapter.
+ *    A DVB-USB-Adapter is basically a dvb_adapter which is present on a USB-device.
  * @caps: capabilities of the DVB USB device.
  * @pid_filter_count: number of PID filter position in the optional hardware
  *  PID-filter.
- *
+ * @streaming_crtl: called to start and stop the MPEG2-TS streaming of the
+ *  device (not URB submitting/killing).
+ * @pid_filter_ctrl: called to en/disable the PID filter, if any.
+ * @pid_filter: called to set/unset a PID for filtering.
+ * @frontend_attach: called to attach the possible frontends (fill fe-field
+ *  of struct dvb_usb_device).
+ * @tuner_attach: called to attach the correct tuner and to fill pll_addr,
+ *  pll_desc and pll_init_buf of struct dvb_usb_device).
+ * @stream: configuration of the USB streaming
+ */
+struct dvb_usb_adapter_properties {
+#define DVB_USB_ADAP_HAS_PID_FILTER               0x01
+#define DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF 0x02
+#define DVB_USB_ADAP_NEED_PID_FILTERING           0x04
+#define DVB_USB_ADAP_RECEIVES_204_BYTE_TS         0x08
+       int caps;
+       int pid_filter_count;
+
+       int (*streaming_ctrl)  (struct dvb_usb_adapter *, int);
+       int (*pid_filter_ctrl) (struct dvb_usb_adapter *, int);
+       int (*pid_filter)      (struct dvb_usb_adapter *, int, u16, int);
+
+       int (*frontend_attach) (struct dvb_usb_adapter *);
+       int (*tuner_attach)    (struct dvb_usb_adapter *);
+
+       struct usb_data_stream_properties stream;
+
+       int size_of_priv;
+};
+
+/**
+ * struct dvb_usb_device_properties - properties of a dvb-usb-device
  * @usb_ctrl: which USB device-side controller is in use. Needed for firmware
  *  download.
  * @firmware: name of the firmware file.
  * @download_firmware: called to download the firmware when the usb_ctrl is
  *  DEVICE_SPECIFIC.
  * @no_reconnect: device doesn't do a reconnect after downloading the firmware,
   so do the warm initialization right after it
-
*  so do the warm initialization right after it
+ *
  * @size_of_priv: how many bytes shall be allocated for the private field
  *  of struct dvb_usb_device.
  *
  * @power_ctrl: called to enable/disable power of the device.
- * @streaming_crtl: called to start and stop the MPEG2-TS streaming of the
- *  device (not URB submitting/killing).
- * @pid_filter_ctrl: called to en/disable the PID filter, if any.
- * @pid_filter: called to set/unset a PID for filtering.
- *
  * @read_mac_address: called to read the MAC address of the device.
- *
- * @frontend_attach: called to attach the possible frontends (fill fe-field
- *  of struct dvb_usb_device).
- * @tuner_attach: called to attach the correct tuner and to fill pll_addr,
- *  pll_desc and pll_init_buf of struct dvb_usb_device).
  * @identify_state: called to determine the state (cold or warm), when it
  *  is not distinguishable by the USB IDs.
  *
@@ -130,50 +180,40 @@ struct dvb_usb_device;
  *  is non-zero, one can use dvb_usb_generic_rw and dvb_usb_generic_write-
  *  helper functions.
  *
- * @urb: describes the kind of USB transfer used for MPEG2-TS-streaming.
- *  (BULK or ISOC)
- *
  * @num_device_descs: number of struct dvb_usb_device_description in @devices
  * @devices: array of struct dvb_usb_device_description compatibles with these
  *  properties.
  */
-struct dvb_usb_properties {
+#define MAX_NO_OF_ADAPTER_PER_DEVICE 2
+struct dvb_usb_device_properties {
 
-#define DVB_USB_HAS_PID_FILTER               0x01
-#define DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF 0x02
-#define DVB_USB_NEED_PID_FILTERING           0x04
-#define DVB_USB_IS_AN_I2C_ADAPTER            0x08
+#define DVB_USB_IS_AN_I2C_ADAPTER            0x01
        int caps;
-       int pid_filter_count;
 
 #define DEVICE_SPECIFIC 0
 #define CYPRESS_AN2135  1
 #define CYPRESS_AN2235  2
 #define CYPRESS_FX2     3
-       int usb_ctrl;
+       int        usb_ctrl;
+       int        (*download_firmware) (struct usb_device *, const struct firmware *);
        const char firmware[FIRMWARE_NAME_MAX];
-       int (*download_firmware) (struct usb_device *, const struct firmware *);
-       int no_reconnect;
+       int        no_reconnect;
 
        int size_of_priv;
 
-       int (*power_ctrl) (struct dvb_usb_device *, int);
-       int (*streaming_ctrl) (struct dvb_usb_device *, int);
-       int (*pid_filter_ctrl) (struct dvb_usb_device *, int);
-       int (*pid_filter) (struct dvb_usb_device *, int, u16, int);
+       int num_adapters;
+       struct dvb_usb_adapter_properties adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
 
+       int (*power_ctrl)       (struct dvb_usb_device *, int);
        int (*read_mac_address) (struct dvb_usb_device *, u8 []);
-       int (*frontend_attach) (struct dvb_usb_device *);
-       int (*tuner_attach) (struct dvb_usb_device *);
-
-       int (*identify_state) (struct usb_device *, struct dvb_usb_properties *,
+       int (*identify_state)   (struct usb_device *, struct dvb_usb_device_properties *,
                        struct dvb_usb_device_description **, int *);
 
 /* remote control properties */
 #define REMOTE_NO_KEY_PRESSED      0x00
 #define REMOTE_KEY_PRESSED         0x01
 #define REMOTE_KEY_REPEAT          0x02
-       struct dvb_usb_rc_key *rc_key_map;
+       struct dvb_usb_rc_key  *rc_key_map;
        int rc_key_map_size;
        int (*rc_query) (struct dvb_usb_device *, u32 *, int *);
        int rc_interval;
@@ -182,40 +222,12 @@ struct dvb_usb_properties {
 
        int generic_bulk_ctrl_endpoint;
 
-       struct {
-#define DVB_USB_BULK  1
-#define DVB_USB_ISOC  2
-               int type;
-               int count;
-               int endpoint;
-
-               union {
-                       struct {
-                               int buffersize; /* per URB */
-                       } bulk;
-                       struct {
-                               int framesperurb;
-                               int framesize;
-                               int interval;
-                       } isoc;
-               } u;
-       } urb;
-
        int num_device_descs;
        struct dvb_usb_device_description devices[9];
 };
 
-
 /**
- * struct dvb_usb_device - object of a DVB USB device
- * @props: copy of the struct dvb_usb_properties this device belongs to.
- * @desc: pointer to the device's struct dvb_usb_device_description.
- * @state: initialization and runtime state of the device.
- *
- * @udev: pointer to the device's struct usb_device.
- * @urb_list: array of dynamically allocated struct urb for the MPEG2-TS-
- *  streaming.
- *
+ * struct usb_data_stream - generic object of an USB stream
  * @buf_num: number of buffer allocated.
  * @buf_size: size of each buffer in buf_list.
  * @buf_list: array containing all allocate buffers for streaming.
@@ -223,18 +235,40 @@ struct dvb_usb_properties {
  *
  * @urbs_initialized: number of URBs initialized.
  * @urbs_submitted: number of URBs submitted.
+ */
+#define MAX_NO_URBS_FOR_DATA_STREAM 10
+struct usb_data_stream {
+       struct usb_device                 *udev;
+       struct usb_data_stream_properties  props;
+
+#define USB_STATE_INIT    0x00
+#define USB_STATE_URB_BUF 0x01
+       int state;
+
+       void (*complete) (struct usb_data_stream *, u8 *, size_t);
+
+       struct urb    *urb_list[MAX_NO_URBS_FOR_DATA_STREAM];
+       int            buf_num;
+       unsigned long  buf_size;
+       u8            *buf_list[MAX_NO_URBS_FOR_DATA_STREAM];
+       dma_addr_t     dma_addr[MAX_NO_URBS_FOR_DATA_STREAM];
+
+       int urbs_initialized;
+       int urbs_submitted;
+
+       void *user_priv;
+};
+
+/**
+ * struct dvb_usb_adapter - a DVB adapter on a USB device
+ * @id: index of this adapter (starting with 0).
  *
  * @feedcount: number of reqested feeds (used for streaming-activation)
  * @pid_filtering: is hardware pid_filtering used or not.
  *
- * @usb_mutex: semaphore of USB control messages (reading needs two messages)
- * @i2c_mutex: semaphore for i2c-transfers
- *
- * @i2c_adap: device's i2c_adapter if it uses I2CoverUSB
  * @pll_addr: I2C address of the tuner for programming
  * @pll_init: array containing the initialization buffer
  * @pll_desc: pointer to the appropriate struct dvb_pll_desc
- *
  * @tuner_pass_ctrl: called to (de)activate tuner passthru of the demod or the board
  *
  * @dvb_adap: device's dvb_adapter.
@@ -244,8 +278,62 @@ struct dvb_usb_properties {
  * @dvb_frontend: device's frontend.
  * @max_feed_count: how many feeds can be handled simultaneously by this
  *  device
+ *
+ * @fe_init:  rerouted frontend-init (wakeup) function.
  * @fe_sleep: rerouted frontend-sleep function.
- * @fe_init: rerouted frontend-init (wakeup) function.
+ *
+ * @stream: the usb data stream.
+ */
+struct dvb_usb_adapter {
+       struct dvb_usb_device *dev;
+       struct dvb_usb_adapter_properties props;
+
+#define DVB_USB_ADAP_STATE_INIT 0x000
+#define DVB_USB_ADAP_STATE_DVB  0x001
+       int state;
+
+       u8  id;
+
+       int feedcount;
+       int pid_filtering;
+
+       /* tuner programming information */
+       u8 pll_addr;
+       u8 pll_init[4];
+       struct dvb_pll_desc *pll_desc;
+       int (*tuner_pass_ctrl) (struct dvb_frontend *, int, u8);
+
+       /* dvb */
+       struct dvb_adapter   dvb_adap;
+       struct dmxdev        dmxdev;
+       struct dvb_demux     demux;
+       struct dvb_net       dvb_net;
+       struct dvb_frontend *fe;
+       int                  max_feed_count;
+
+       int (*fe_init)  (struct dvb_frontend *);
+       int (*fe_sleep) (struct dvb_frontend *);
+
+       struct usb_data_stream stream;
+
+       void *priv;
+};
+
+/**
+ * struct dvb_usb_device - object of a DVB USB device
+ * @props: copy of the struct dvb_usb_properties this device belongs to.
+ * @desc: pointer to the device's struct dvb_usb_device_description.
+ * @state: initialization and runtime state of the device.
+ *
+ * @powered: indicated whether the device is power or not.
+ *  Powered is in/decremented for each call to modify the state.
+ * @udev: pointer to the device's struct usb_device.
+ *
+ * @usb_mutex: semaphore of USB control messages (reading needs two messages)
+ * @i2c_mutex: semaphore for i2c-transfers
+ *
+ * @i2c_adap: device's i2c_adapter if it uses I2CoverUSB
+ *
  * @rc_input_dev: input device for the remote control.
  * @rc_query_work: struct work_struct frequent rc queries
  * @last_event: last triggered event
@@ -255,32 +343,18 @@ struct dvb_usb_properties {
  *  in size_of_priv of dvb_usb_properties).
  */
 struct dvb_usb_device {
-       struct dvb_usb_properties props;
+       struct dvb_usb_device_properties props;
        struct dvb_usb_device_description *desc;
 
-#define DVB_USB_STATE_INIT        0x000
-#define DVB_USB_STATE_URB_LIST    0x001
-#define DVB_USB_STATE_URB_BUF     0x002
-#define DVB_USB_STATE_DVB         0x004
-#define DVB_USB_STATE_I2C         0x008
-#define DVB_USB_STATE_REMOTE      0x010
-#define DVB_USB_STATE_URB_SUBMIT  0x020
-       int state;
-
-       /* usb */
        struct usb_device *udev;
-       struct urb **urb_list;
 
-       int buf_num;
-       unsigned long buf_size;
-       u8 **buf_list;
-       dma_addr_t *dma_addr;
-
-       int urbs_initialized;
-       int urbs_submitted;
+#define DVB_USB_STATE_INIT        0x000
+#define DVB_USB_STATE_I2C         0x001
+#define DVB_USB_STATE_DVB         0x002
+#define DVB_USB_STATE_REMOTE      0x004
+       int state;
 
-       int feedcount;
-       int pid_filtering;
+       int powered;
 
        /* locking */
        struct mutex usb_mutex;
@@ -289,22 +363,8 @@ struct dvb_usb_device {
        struct mutex i2c_mutex;
        struct i2c_adapter i2c_adap;
 
-       /* tuner programming information */
-       u8 pll_addr;
-       u8 pll_init[4];
-       struct dvb_pll_desc *pll_desc;
-       int (*tuner_pass_ctrl)(struct dvb_frontend *, int, u8);
-
-       /* dvb */
-       struct dvb_adapter dvb_adap;
-       struct dmxdev dmxdev;
-       struct dvb_demux demux;
-       struct dvb_net dvb_net;
-       struct dvb_frontend* fe;
-       int max_feed_count;
-
-       int (*fe_sleep) (struct dvb_frontend *);
-       int (*fe_init)  (struct dvb_frontend *);
+       int                    num_adapters_initialized;
+       struct dvb_usb_adapter adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
 
        /* remote control */
        struct input_dev *rc_input_dev;
@@ -318,7 +378,7 @@ struct dvb_usb_device {
        void *priv;
 };
 
-extern int dvb_usb_device_init(struct usb_interface *, struct dvb_usb_properties *, struct module *, struct dvb_usb_device **);
+extern int dvb_usb_device_init(struct usb_interface *, struct dvb_usb_device_properties *, struct module *, struct dvb_usb_device **);
 extern void dvb_usb_device_exit(struct usb_interface *);
 
 /* the generic read/write method for device control */
@@ -342,5 +402,7 @@ struct hexline {
        u8 chk;
 };
 extern int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type);
+extern int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, int *pos);
+
 
 #endif
index 9a98f3fdae318c98a019ce20497372ce3fb9d8e9..7375eb20166dfecb39497d5d91abf3f138c17eeb 100644 (file)
@@ -161,19 +161,18 @@ static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
 }
 
 
-static int gp8psk_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 {
-       return gp8psk_usb_out_op(d, ARM_TRANSFER, onoff, 0 , NULL, 0);
+       return gp8psk_usb_out_op(adap->dev, ARM_TRANSFER, onoff, 0 , NULL, 0);
 }
 
-static int gp8psk_frontend_attach(struct dvb_usb_device *d)
+static int gp8psk_frontend_attach(struct dvb_usb_adapter *adap)
 {
-       d->fe = gp8psk_fe_attach(d);
-
+       adap->fe = gp8psk_fe_attach(adap->dev);
        return 0;
 }
 
-static struct dvb_usb_properties gp8psk_properties;
+static struct dvb_usb_device_properties gp8psk_properties;
 
 static int gp8psk_usb_probe(struct usb_interface *intf,
                const struct usb_device_id *id)
@@ -188,20 +187,18 @@ static struct usb_device_id gp8psk_usb_table [] = {
 };
 MODULE_DEVICE_TABLE(usb, gp8psk_usb_table);
 
-static struct dvb_usb_properties gp8psk_properties = {
-       .caps = 0,
-
+static struct dvb_usb_device_properties gp8psk_properties = {
        .usb_ctrl = CYPRESS_FX2,
        .firmware = "dvb-usb-gp8psk-01.fw",
 
+       .num_adapters = 1,
+       .adapter = {
+               {
        .streaming_ctrl   = gp8psk_streaming_ctrl,
-       .power_ctrl       = gp8psk_power_ctrl,
        .frontend_attach  = gp8psk_frontend_attach,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
        /* parameter for the MPEG2-data transfer */
-       .urb = {
-               .type = DVB_USB_BULK,
+                       .stream = {
+                               .type = USB_BULK,
                .count = 7,
                .endpoint = 0x82,
                .u = {
@@ -210,6 +207,11 @@ static struct dvb_usb_properties gp8psk_properties = {
                        }
                }
        },
+               }
+       },
+       .power_ctrl       = gp8psk_power_ctrl,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
 
        .num_device_descs = 1,
        .devices = {
@@ -217,7 +219,7 @@ static struct dvb_usb_properties gp8psk_properties = {
                  .cold_ids = { &gp8psk_usb_table[0], NULL },
                  .warm_ids = { &gp8psk_usb_table[1], NULL },
                },
-               { 0 },
+               { NULL },
        }
 };
 
index 79f0a02ce98719742b3ad83791145c0041e2228d..a9219bf69b8927faf0da389c1dddddc06742ef7e 100644 (file)
@@ -135,7 +135,7 @@ static int nova_t_read_mac_address (struct dvb_usb_device *d, u8 mac[6])
 }
 
 /* USB Driver stuff */
-static struct dvb_usb_properties nova_t_properties;
+static struct dvb_usb_device_properties nova_t_properties;
 
 static int nova_t_probe(struct usb_interface *intf,
                const struct usb_device_id *id)
@@ -151,34 +151,27 @@ static struct usb_device_id nova_t_table [] = {
 };
 MODULE_DEVICE_TABLE(usb, nova_t_table);
 
-static struct dvb_usb_properties nova_t_properties = {
-       .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
-       .pid_filter_count = 32,
+static struct dvb_usb_device_properties nova_t_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
        .usb_ctrl = CYPRESS_FX2,
        .firmware = "dvb-usb-nova-t-usb2-02.fw",
 
-       .size_of_priv     = sizeof(struct dibusb_state),
+       .num_adapters     = 1,
+       .adapter          = {
+               {
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                       .pid_filter_count = 32,
 
        .streaming_ctrl   = dibusb2_0_streaming_ctrl,
        .pid_filter       = dibusb_pid_filter,
        .pid_filter_ctrl  = dibusb_pid_filter_ctrl,
-       .power_ctrl       = dibusb2_0_power_ctrl,
        .frontend_attach  = dibusb_dib3000mc_frontend_attach,
        .tuner_attach     = dibusb_dib3000mc_tuner_attach,
-       .read_mac_address = nova_t_read_mac_address,
-
-       .rc_interval      = 100,
-       .rc_key_map       = haupp_rc_keys,
-       .rc_key_map_size  = ARRAY_SIZE(haupp_rc_keys),
-       .rc_query         = nova_t_rc_query,
 
-       .i2c_algo         = &dibusb_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
        /* parameter for the MPEG2-data transfer */
-       .urb = {
-               .type = DVB_USB_BULK,
+                       .stream = {
+                               .type = USB_BULK,
                .count = 7,
                .endpoint = 0x06,
                .u = {
@@ -188,6 +181,22 @@ static struct dvb_usb_properties nova_t_properties = {
                }
        },
 
+                       .size_of_priv     = sizeof(struct dibusb_state),
+               }
+       },
+
+       .power_ctrl       = dibusb2_0_power_ctrl,
+       .read_mac_address = nova_t_read_mac_address,
+
+       .rc_interval      = 100,
+       .rc_key_map       = haupp_rc_keys,
+       .rc_key_map_size  = ARRAY_SIZE(haupp_rc_keys),
+       .rc_query         = nova_t_rc_query,
+
+       .i2c_algo         = &dibusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
        .num_device_descs = 1,
        .devices = {
                {   "Hauppauge WinTV-NOVA-T usb2",
index 418a0b707151c9071f9833d6e52f49027bd1e20f..f9941ea88b3e5996de3d7ecbbc061fc0e44b3b5e 100644 (file)
@@ -50,7 +50,7 @@ static int umt_mt352_demod_init(struct dvb_frontend *fe)
        return 0;
 }
 
-static int umt_mt352_frontend_attach(struct dvb_usb_device *d)
+static int umt_mt352_frontend_attach(struct dvb_usb_adapter *adap)
 {
        struct mt352_config umt_config;
 
@@ -58,21 +58,21 @@ static int umt_mt352_frontend_attach(struct dvb_usb_device *d)
        umt_config.demod_init = umt_mt352_demod_init;
        umt_config.demod_address = 0xf;
 
-       d->fe = dvb_attach(mt352_attach, &umt_config, &d->i2c_adap);
+       adap->fe = dvb_attach(mt352_attach, &umt_config, &adap->dev->i2c_adap);
 
        return 0;
 }
 
-static int umt_tuner_attach (struct dvb_usb_device *d)
+static int umt_tuner_attach (struct dvb_usb_adapter *adap)
 {
-       d->pll_addr = 0x61;
-       d->pll_desc = &dvb_pll_tua6034;
-       d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
+       adap->pll_addr = 0x61;
+       adap->pll_desc = &dvb_pll_tua6034;
+       adap->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
        return 0;
 }
 
 /* USB Driver stuff */
-static struct dvb_usb_properties umt_properties;
+static struct dvb_usb_device_properties umt_properties;
 
 static int umt_probe(struct usb_interface *intf,
                const struct usb_device_id *id)
@@ -90,25 +90,22 @@ static struct usb_device_id umt_table [] = {
 };
 MODULE_DEVICE_TABLE (usb, umt_table);
 
-static struct dvb_usb_properties umt_properties = {
+static struct dvb_usb_device_properties umt_properties = {
        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
        .usb_ctrl = CYPRESS_FX2,
        .firmware = "dvb-usb-umt-010-02.fw",
 
-       .size_of_priv     = sizeof(struct dibusb_state),
-
+       .num_adapters = 1,
+       .adapter = {
+               {
        .streaming_ctrl   = dibusb2_0_streaming_ctrl,
-       .power_ctrl       = dibusb_power_ctrl,
        .frontend_attach  = umt_mt352_frontend_attach,
        .tuner_attach     = umt_tuner_attach,
 
-       .i2c_algo         = &dibusb_i2c_algo,
-
-       .generic_bulk_ctrl_endpoint = 0x01,
        /* parameter for the MPEG2-data transfer */
-       .urb = {
-               .type = DVB_USB_BULK,
+                       .stream = {
+                               .type = USB_BULK,
                .count = 20,
                .endpoint = 0x06,
                .u = {
@@ -118,6 +115,15 @@ static struct dvb_usb_properties umt_properties = {
                }
        },
 
+                       .size_of_priv     = sizeof(struct dibusb_state),
+               }
+       },
+       .power_ctrl       = dibusb_power_ctrl,
+
+       .i2c_algo         = &dibusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
        .num_device_descs = 1,
        .devices = {
                {       "Hanftek UMT-010 DVB-T USB2.0",
diff --git a/drivers/media/dvb/dvb-usb/usb-urb.c b/drivers/media/dvb/dvb-usb/usb-urb.c
new file mode 100644 (file)
index 0000000..8728cf3
--- /dev/null
@@ -0,0 +1,242 @@
+/* usb-urb.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file keeps functions for initializing and handling the
+ * BULK and ISOC USB data transfers in a generic way.
+ * Can be used for DVB-only and also, that's the plan, for
+ * Hybrid USB devices (analog and DVB).
+ */
+#include "dvb-usb-common.h"
+
+/* URB stuff for streaming */
+static void usb_urb_complete(struct urb *urb, struct pt_regs *ptregs)
+{
+       struct usb_data_stream *stream = urb->context;
+       int ptype = usb_pipetype(urb->pipe);
+       int i;
+       u8 *b;
+
+       deb_uxfer("'%s' urb completed. status: %d, length: %d/%d, pack_num: %d, errors: %d\n",
+               ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk",
+               urb->status,urb->actual_length,urb->transfer_buffer_length,
+               urb->number_of_packets,urb->error_count);
+
+       switch (urb->status) {
+               case 0:         /* success */
+               case -ETIMEDOUT:    /* NAK */
+                       break;
+               case -ECONNRESET:   /* kill */
+               case -ENOENT:
+               case -ESHUTDOWN:
+                       return;
+               default:        /* error */
+                       deb_ts("urb completition error %d.\n", urb->status);
+                       break;
+       }
+
+       b = (u8 *) urb->transfer_buffer;
+       switch (ptype) {
+               case PIPE_ISOCHRONOUS:
+                       for (i = 0; i < urb->number_of_packets; i++) {
+
+                               if (urb->iso_frame_desc[i].status != 0)
+                                       deb_ts("iso frame descriptor has an error: %d\n",urb->iso_frame_desc[i].status);
+                               else if (urb->iso_frame_desc[i].actual_length > 0)
+                                       stream->complete(stream, b + urb->iso_frame_desc[i].offset, urb->iso_frame_desc[i].actual_length);
+
+                               urb->iso_frame_desc[i].status = 0;
+                               urb->iso_frame_desc[i].actual_length = 0;
+                       }
+                       debug_dump(b,20,deb_uxfer);
+                       break;
+               case PIPE_BULK:
+                       if (urb->actual_length > 0)
+                               stream->complete(stream, b, urb->actual_length);
+                       break;
+               default:
+                       err("unkown endpoint type in completition handler.");
+                       return;
+       }
+       usb_submit_urb(urb,GFP_ATOMIC);
+}
+
+int usb_urb_kill(struct usb_data_stream *stream)
+{
+       int i;
+       for (i = 0; i < stream->urbs_submitted; i++) {
+               deb_ts("killing URB no. %d.\n",i);
+
+               /* stop the URB */
+               usb_kill_urb(stream->urb_list[i]);
+       }
+       stream->urbs_submitted = 0;
+       return 0;
+}
+
+int usb_urb_submit(struct usb_data_stream *stream)
+{
+       int i,ret;
+       for (i = 0; i < stream->urbs_initialized; i++) {
+               deb_ts("submitting URB no. %d\n",i);
+               if ((ret = usb_submit_urb(stream->urb_list[i],GFP_ATOMIC))) {
+                       err("could not submit URB no. %d - get them all back",i);
+                       usb_urb_kill(stream);
+                       return ret;
+               }
+               stream->urbs_submitted++;
+       }
+       return 0;
+}
+
+static int usb_free_stream_buffers(struct usb_data_stream *stream)
+{
+       if (stream->state & USB_STATE_URB_BUF) {
+               while (stream->buf_num) {
+                       stream->buf_num--;
+                       deb_mem("freeing buffer %d\n",stream->buf_num);
+                       usb_buffer_free(stream->udev, stream->buf_size,
+                                       stream->buf_list[stream->buf_num], stream->dma_addr[stream->buf_num]);
+               }
+       }
+
+       stream->state &= ~USB_STATE_URB_BUF;
+
+       return 0;
+}
+
+static int usb_allocate_stream_buffers(struct usb_data_stream *stream, int num, unsigned long size)
+{
+       stream->buf_num = 0;
+       stream->buf_size = size;
+
+       deb_mem("all in all I will use %lu bytes for streaming\n",num*size);
+
+       for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) {
+               deb_mem("allocating buffer %d\n",stream->buf_num);
+               if (( stream->buf_list[stream->buf_num] =
+                                       usb_buffer_alloc(stream->udev, size, SLAB_ATOMIC,
+                                       &stream->dma_addr[stream->buf_num]) ) == NULL) {
+                       deb_mem("not enough memory for urb-buffer allocation.\n");
+                       usb_free_stream_buffers(stream);
+                       return -ENOMEM;
+               }
+               deb_mem("buffer %d: %p (dma: %u)\n",
+                       stream->buf_num, stream->buf_list[stream->buf_num], stream->dma_addr[stream->buf_num]);
+               memset(stream->buf_list[stream->buf_num],0,size);
+               stream->state |= USB_STATE_URB_BUF;
+       }
+       deb_mem("allocation successful\n");
+
+       return 0;
+}
+
+static int usb_bulk_urb_init(struct usb_data_stream *stream)
+{
+       int i;
+
+       if ((i = usb_allocate_stream_buffers(stream,stream->props.count,
+                                       stream->props.u.bulk.buffersize)) < 0)
+               return i;
+
+       /* allocate the URBs */
+       for (i = 0; i < stream->props.count; i++) {
+               if ((stream->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC)) == NULL)
+                       return -ENOMEM;
+
+               usb_fill_bulk_urb( stream->urb_list[i], stream->udev,
+                               usb_rcvbulkpipe(stream->udev,stream->props.endpoint),
+                               stream->buf_list[i],
+                               stream->props.u.bulk.buffersize,
+                               usb_urb_complete, stream);
+
+               stream->urb_list[i]->transfer_flags = 0;
+               stream->urbs_initialized++;
+       }
+       return 0;
+}
+
+static int usb_isoc_urb_init(struct usb_data_stream *stream)
+{
+       int i,j;
+
+       if ((i = usb_allocate_stream_buffers(stream,stream->props.count,
+                                       stream->props.u.isoc.framesize*stream->props.u.isoc.framesperurb)) < 0)
+               return i;
+
+       /* allocate the URBs */
+       for (i = 0; i < stream->props.count; i++) {
+               struct urb *urb;
+               int frame_offset = 0;
+               if ((stream->urb_list[i] =
+                                       usb_alloc_urb(stream->props.u.isoc.framesperurb,GFP_ATOMIC)) == NULL)
+                       return -ENOMEM;
+
+               urb = stream->urb_list[i];
+
+               urb->dev = stream->udev;
+               urb->context = stream;
+               urb->complete = usb_urb_complete;
+               urb->pipe = usb_rcvisocpipe(stream->udev,stream->props.endpoint);
+               urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
+               urb->interval = stream->props.u.isoc.interval;
+               urb->number_of_packets = stream->props.u.isoc.framesperurb;
+               urb->transfer_buffer_length = stream->buf_size;
+               urb->transfer_buffer = stream->buf_list[i];
+               urb->transfer_dma = stream->dma_addr[i];
+
+               for (j = 0; j < stream->props.u.isoc.framesperurb; j++) {
+                       urb->iso_frame_desc[j].offset = frame_offset;
+                       urb->iso_frame_desc[j].length = stream->props.u.isoc.framesize;
+                       frame_offset += stream->props.u.isoc.framesize;
+               }
+
+               stream->urbs_initialized++;
+       }
+       return 0;
+}
+
+int usb_urb_init(struct usb_data_stream *stream, struct usb_data_stream_properties *props)
+{
+       if (stream == NULL || props == NULL)
+               return -EINVAL;
+
+       memcpy(&stream->props, props, sizeof(*props));
+
+       usb_clear_halt(stream->udev,usb_rcvbulkpipe(stream->udev,stream->props.endpoint));
+
+       if (stream->complete == NULL) {
+               err("there is no data callback - this doesn't make sense.");
+               return -EINVAL;
+       }
+
+       switch (stream->props.type) {
+               case USB_BULK:
+                       return usb_bulk_urb_init(stream);
+               case USB_ISOC:
+                       return usb_isoc_urb_init(stream);
+               default:
+                       err("unkown URB-type for data transfer.");
+                       return -EINVAL;
+       }
+}
+
+int usb_urb_exit(struct usb_data_stream *stream)
+{
+       int i;
+
+       usb_urb_kill(stream);
+
+       for (i = 0; i < stream->urbs_initialized; i++) {
+               if (stream->urb_list[i] != NULL) {
+                       deb_mem("freeing URB no. %d.\n",i);
+                       /* free the URBs */
+                       usb_free_urb(stream->urb_list[i]);
+               }
+       }
+       stream->urbs_initialized = 0;
+
+       usb_free_stream_buffers(stream);
+       return 0;
+}
index d4da494132ec7814f0d818ce3fda6d21dcc9a201..3ecb2e0ce80f7ec986023b014a8a249b1fe7dadb 100644 (file)
@@ -24,6 +24,8 @@ struct vp702x_fe_state {
        struct dvb_frontend fe;
        struct dvb_usb_device *d;
 
+       struct dvb_frontend_ops ops;
+
        fe_sec_voltage_t voltage;
        fe_sec_tone_mode_t tone_mode;
 
@@ -72,9 +74,6 @@ static int vp702x_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
        else
                *status = 0;
 
-       deb_fe("real state: %x\n",*status);
-       *status = 0x1f;
-
        if (*status & FE_HAS_LOCK)
                st->status_check_interval = 1000;
        else
@@ -171,8 +170,6 @@ static int vp702x_fe_set_frontend(struct dvb_frontend* fe,
        st->status_check_interval = 250;
        st->next_status_check = jiffies;
 
-       vp702x_usb_in_op(st->d, RESET_TUNER, 0, 0, NULL, 0);
-       msleep(30);
        vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
 
        if (ibuf[2] == 0 && ibuf[3] == 0)
@@ -183,6 +180,20 @@ static int vp702x_fe_set_frontend(struct dvb_frontend* fe,
        return 0;
 }
 
+static int vp702x_fe_init(struct dvb_frontend *fe)
+{
+       struct vp702x_fe_state *st = fe->demodulator_priv;
+       deb_fe("%s\n",__FUNCTION__);
+       vp702x_usb_in_op(st->d, RESET_TUNER, 0, 0, NULL, 0);
+       return 0;
+}
+
+static int vp702x_fe_sleep(struct dvb_frontend *fe)
+{
+       deb_fe("%s\n",__FUNCTION__);
+       return 0;
+}
+
 static int vp702x_fe_get_frontend(struct dvb_frontend* fe,
                                  struct dvb_frontend_parameters *fep)
 {
@@ -193,8 +204,8 @@ static int vp702x_fe_get_frontend(struct dvb_frontend* fe,
 static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
                                    struct dvb_diseqc_master_cmd *m)
 {
-       struct vp702x_fe_state *st = fe->demodulator_priv;
-       u8 cmd[8],ibuf[10];
+       //struct vp702x_fe_state *st = fe->demodulator_priv;
+       u8 cmd[8];//,ibuf[10];
        memset(cmd,0,8);
 
        deb_fe("%s\n",__FUNCTION__);
@@ -207,12 +218,12 @@ static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
        memcpy(&cmd[3], m->msg, m->msg_len);
        cmd[7] = vp702x_chksum(cmd,0,7);
 
-       vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
+//     vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
 
-       if (ibuf[2] == 0 && ibuf[3] == 0)
-               deb_fe("diseqc cmd failed.\n");
-       else
-               deb_fe("diseqc cmd succeeded.\n");
+//     if (ibuf[2] == 0 && ibuf[3] == 0)
+//             deb_fe("diseqc cmd failed.\n");
+//     else
+//             deb_fe("diseqc cmd succeeded.\n");
 
        return 0;
 }
@@ -318,8 +329,8 @@ static struct dvb_frontend_ops vp702x_fe_ops = {
        },
        .release = vp702x_fe_release,
 
-       .init = NULL,
-       .sleep = NULL,
+       .init  = vp702x_fe_init,
+       .sleep = vp702x_fe_sleep,
 
        .set_frontend = vp702x_fe_set_frontend,
        .get_frontend = vp702x_fe_get_frontend,
index b2f098a2d5f7ee31f8baa891fcd784a0d2497532..02bd61aaac666b3c6d1b5156ccc1d597dbda2f0b 100644 (file)
@@ -22,50 +22,54 @@ module_param_named(debug,dvb_usb_vp702x_debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
 
 struct vp702x_state {
-       u8 pid_table[17]; /* [16] controls the pid_table state */
+       int pid_filter_count;
+       int pid_filter_can_bypass;
+       u8  pid_filter_state;
+};
+
+struct vp702x_device_state {
+       u8 power_state;
 };
 
 /* check for mutex FIXME */
 int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
 {
-       int ret = 0,try = 0;
+       int ret = -1;
 
-       while (ret >= 0 && ret != blen && try < 3) {
                ret = usb_control_msg(d->udev,
                        usb_rcvctrlpipe(d->udev,0),
                        req,
                        USB_TYPE_VENDOR | USB_DIR_IN,
                        value,index,b,blen,
                        2000);
-               deb_info("reading number %d (ret: %d)\n",try,ret);
-               try++;
-       }
 
-       if (ret < 0 || ret != blen) {
-               warn("usb in operation failed.");
+       if (ret < 0) {
+               warn("usb in operation failed. (%d)", ret);
                ret = -EIO;
        } else
                ret = 0;
 
-       deb_xfer("in: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
+
+       deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index);
        debug_dump(b,blen,deb_xfer);
 
        return ret;
 }
 
-static int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
+int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
                             u16 index, u8 *b, int blen)
 {
-       deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
+       int ret;
+       deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index);
        debug_dump(b,blen,deb_xfer);
 
-       if (usb_control_msg(d->udev,
+       if ((ret = usb_control_msg(d->udev,
                        usb_sndctrlpipe(d->udev,0),
                        req,
                        USB_TYPE_VENDOR | USB_DIR_OUT,
                        value,index,b,blen,
-                       2000) != blen) {
-               warn("usb out operation failed.");
+                       2000)) != blen) {
+               warn("usb out operation failed. (%d)",ret);
                return -EIO;
        } else
                return 0;
@@ -78,12 +82,10 @@ int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int il
        if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
                return ret;
 
-       if ((ret = vp702x_usb_out_op(d,REQUEST_OUT,0,0,o,olen)) < 0)
-               goto unlock;
+       ret = vp702x_usb_out_op(d,REQUEST_OUT,0,0,o,olen);
        msleep(msec);
        ret = vp702x_usb_in_op(d,REQUEST_IN,0,0,i,ilen);
 
-unlock:
        mutex_unlock(&d->usb_mutex);
 
        return ret;
@@ -108,29 +110,65 @@ static int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o,
        return ret;
 }
 
-static int vp702x_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff)
+static int vp702x_set_pld_mode(struct dvb_usb_adapter *adap, u8 bypass)
+{
+       u8 buf[16] = { 0 };
+       return vp702x_usb_in_op(adap->dev, 0xe0, (bypass << 8) | 0x0e, 0, buf, 16);
+}
+
+static int vp702x_set_pld_state(struct dvb_usb_adapter *adap, u8 state)
+{
+       u8 buf[16] = { 0 };
+       return vp702x_usb_in_op(adap->dev, 0xe0, (state << 8) | 0x0f, 0, buf, 16);
+}
+
+static int vp702x_set_pid(struct dvb_usb_adapter *adap, u16 pid, u8 id, int onoff)
 {
-       struct vp702x_state *st = d->priv;
-       u8 buf[9];
-
-       if (onoff) {
-               st->pid_table[16]   |=   1 << index;
-               st->pid_table[index*2]   = (pid >> 8) & 0xff;
-               st->pid_table[index*2+1] =  pid       & 0xff;
-       } else {
-               st->pid_table[16]   &= ~(1 << index);
-               st->pid_table[index*2] = st->pid_table[index*2+1] = 0;
+       struct vp702x_state *st = adap->priv;
+       u8 buf[16] = { 0 };
+
+       if (onoff)
+               st->pid_filter_state |=  (1 << id);
+       else {
+               st->pid_filter_state &= ~(1 << id);
+               pid = 0xffff;
        }
 
-       return vp702x_usb_inout_cmd(d,SET_PID_FILTER,st->pid_table,17,buf,9,10);
+       id = 0x10 + id*2;
+
+       vp702x_set_pld_state(adap, st->pid_filter_state);
+       vp702x_usb_in_op(adap->dev, 0xe0, (((pid >> 8) & 0xff) << 8) | (id), 0, buf, 16);
+       vp702x_usb_in_op(adap->dev, 0xe0, (((pid     ) & 0xff) << 8) | (id+1), 0, buf, 16);
+       return 0;
 }
 
-static int vp702x_power_ctrl(struct dvb_usb_device *d, int onoff)
+
+static int vp702x_init_pid_filter(struct dvb_usb_adapter *adap)
 {
-       vp702x_usb_in_op(d,RESET_TUNER,0,0,NULL,0);
+       struct vp702x_state *st = adap->priv;
+       int i;
+       u8 b[10] = { 0 };
+
+       st->pid_filter_count = 8;
+       st->pid_filter_can_bypass = 1;
+       st->pid_filter_state = 0x00;
+
+       vp702x_set_pld_mode(adap, 1); // bypass
+
+       for (i = 0; i < st->pid_filter_count; i++)
+               vp702x_set_pid(adap, 0xffff, i, 1);
 
-       vp702x_usb_in_op(d,SET_TUNER_POWER_REQ,0,onoff,NULL,0);
-       return vp702x_usb_in_op(d,SET_TUNER_POWER_REQ,0,onoff,NULL,0);
+       vp702x_usb_in_op(adap->dev, 0xb5, 3, 0, b, 10);
+       vp702x_usb_in_op(adap->dev, 0xb5, 0, 0, b, 10);
+       vp702x_usb_in_op(adap->dev, 0xb5, 1, 0, b, 10);
+
+       //vp702x_set_pld_mode(d, 0); // filter
+       return 0;
+}
+
+static int vp702x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+       return 0;
 }
 
 /* keys for the enclosed remote control */
@@ -166,74 +204,83 @@ static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
        return 0;
 }
 
+int vp702x_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       struct vp702x_device_state *st = d->priv;
+
+       if (st->power_state == 0 && onoff)
+               vp702x_usb_out_op(d, SET_TUNER_POWER_REQ, 1, 7, NULL, 0);
+       else if (st->power_state == 1 && onoff == 0)
+               vp702x_usb_out_op(d, SET_TUNER_POWER_REQ, 0, 7, NULL, 0);
+
+       st->power_state = onoff;
+
+       return 0;
+}
+
 static int vp702x_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
 {
-       u8 macb[9];
-       if (vp702x_usb_inout_cmd(d, GET_MAC_ADDRESS, NULL, 0, macb, 9, 10))
-               return -EIO;
-       memcpy(mac,&macb[3],6);
+       u8 i;
+       for (i = 6; i < 12; i++)
+               vp702x_usb_in_op(d, READ_EEPROM_REQ, i, 1, &mac[i - 6], 1);
        return 0;
 }
 
-static int vp702x_frontend_attach(struct dvb_usb_device *d)
+static int vp702x_frontend_attach(struct dvb_usb_adapter *adap)
 {
-       u8 buf[9] = { 0 };
+       u8 buf[10] = { 0 };
+
+       vp702x_usb_out_op(adap->dev, SET_TUNER_POWER_REQ, 0, 7, NULL, 0);
 
-       if (vp702x_usb_inout_cmd(d, GET_SYSTEM_STRING, NULL, 0, buf, 9, 10))
+       if (vp702x_usb_inout_cmd(adap->dev, GET_SYSTEM_STRING, NULL, 0, buf, 10, 10))
                return -EIO;
 
-       buf[8] = '\0';
+       buf[9] = '\0';
        info("system string: %s",&buf[1]);
 
-       d->fe = vp702x_fe_attach(d);
+       vp702x_init_pid_filter(adap);
+
+       adap->fe = vp702x_fe_attach(adap->dev);
+       vp702x_usb_out_op(adap->dev, SET_TUNER_POWER_REQ, 1, 7, NULL, 0);
+
        return 0;
 }
 
-static struct dvb_usb_properties vp702x_properties;
+static struct dvb_usb_device_properties vp702x_properties;
 
 static int vp702x_usb_probe(struct usb_interface *intf,
                const struct usb_device_id *id)
 {
-       struct usb_device *udev = interface_to_usbdev(intf);
-
-       usb_clear_halt(udev,usb_sndctrlpipe(udev,0));
-       usb_clear_halt(udev,usb_rcvctrlpipe(udev,0));
-
        return dvb_usb_device_init(intf,&vp702x_properties,THIS_MODULE,NULL);
 }
 
 static struct usb_device_id vp702x_usb_table [] = {
            { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7021_COLD) },
-           { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7021_WARM) },
-           { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_COLD) },
-           { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_WARM) },
+//         { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_COLD) },
+//         { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_WARM) },
            { 0 },
 };
 MODULE_DEVICE_TABLE(usb, vp702x_usb_table);
 
-static struct dvb_usb_properties vp702x_properties = {
-       .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
-       .pid_filter_count = 8, /* !!! */
-
+static struct dvb_usb_device_properties vp702x_properties = {
        .usb_ctrl = CYPRESS_FX2,
-       .firmware = "dvb-usb-vp702x-01.fw",
+       .firmware            = "dvb-usb-vp702x-02.fw",
+       .no_reconnect        = 1,
 
-       .pid_filter       = vp702x_pid_filter,
-       .power_ctrl       = vp702x_power_ctrl,
-       .frontend_attach  = vp702x_frontend_attach,
-       .read_mac_address = vp702x_read_mac_addr,
+       .size_of_priv     = sizeof(struct vp702x_device_state),
 
-       .rc_key_map       = vp702x_rc_keys,
-       .rc_key_map_size  = ARRAY_SIZE(vp702x_rc_keys),
-       .rc_interval      = 400,
-       .rc_query         = vp702x_rc_query,
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .caps             = DVB_USB_ADAP_RECEIVES_204_BYTE_TS,
 
-       .size_of_priv     = sizeof(struct vp702x_state),
+                       .streaming_ctrl   = vp702x_streaming_ctrl,
+       .frontend_attach  = vp702x_frontend_attach,
 
        /* parameter for the MPEG2-data transfer */
-       .urb = {
-               .type = DVB_USB_BULK,
-               .count = 7,
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 10,
                .endpoint = 0x02,
                .u = {
                        .bulk = {
@@ -241,24 +288,33 @@ static struct dvb_usb_properties vp702x_properties = {
                        }
                }
        },
+                       .size_of_priv     = sizeof(struct vp702x_state),
+               }
+               },
+       .read_mac_address = vp702x_read_mac_addr,
+
+       .rc_key_map       = vp702x_rc_keys,
+       .rc_key_map_size  = ARRAY_SIZE(vp702x_rc_keys),
+       .rc_interval      = 400,
+       .rc_query         = vp702x_rc_query,
 
-       .num_device_descs = 2,
+       .num_device_descs = 1,
        .devices = {
                { .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7021)",
                  .cold_ids = { &vp702x_usb_table[0], NULL },
-                 .warm_ids = { &vp702x_usb_table[1], NULL },
+                 .warm_ids = { NULL },
                },
-               { .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7020)",
+/*             { .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7020)",
                  .cold_ids = { &vp702x_usb_table[2], NULL },
                  .warm_ids = { &vp702x_usb_table[3], NULL },
                },
-               { 0 },
+*/             { NULL },
        }
 };
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver vp702x_usb_driver = {
-       .name           = "dvb-usb-vp702x",
+       .name           = "dvb_usb_vp702x",
        .probe          = vp702x_usb_probe,
        .disconnect = dvb_usb_device_exit,
        .id_table       = vp702x_usb_table,
@@ -287,5 +343,5 @@ module_exit(vp702x_usb_module_exit);
 
 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
 MODULE_DESCRIPTION("Driver for Twinhan StarBox DVB-S USB2.0 and clones");
-MODULE_VERSION("1.0-alpha");
+MODULE_VERSION("1.0");
 MODULE_LICENSE("GPL");
index c2f97f96c21fc1feae79ac7caa455cb641d1e8f0..25a9dee4c824328fc6c27be4fd4730f1c2632efe 100644 (file)
@@ -102,5 +102,7 @@ extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d);
 
 extern int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec);
 extern int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
+extern int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
+extern int vp702x_power_ctrl(struct dvb_usb_device *d, int onoff);
 
 #endif
index 8ea3834a6cf8a2091d9908081c6e5f85ee69d618..b4cf002703a753dd0e4be529ca5e29b7d92d9952 100644 (file)
@@ -169,31 +169,31 @@ static int vp7045_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
        return vp7045_read_eeprom(d,mac, 6, MAC_0_ADDR);
 }
 
-static int vp7045_frontend_attach(struct dvb_usb_device *d)
+static int vp7045_frontend_attach(struct dvb_usb_adapter *adap)
 {
        u8 buf[255] = { 0 };
 
-       vp7045_usb_op(d,VENDOR_STRING_READ,NULL,0,buf,20,0);
+       vp7045_usb_op(adap->dev,VENDOR_STRING_READ,NULL,0,buf,20,0);
        buf[10] = '\0';
        deb_info("firmware says: %s ",buf);
 
-       vp7045_usb_op(d,PRODUCT_STRING_READ,NULL,0,buf,20,0);
+       vp7045_usb_op(adap->dev,PRODUCT_STRING_READ,NULL,0,buf,20,0);
        buf[10] = '\0';
        deb_info("%s ",buf);
 
-       vp7045_usb_op(d,FW_VERSION_READ,NULL,0,buf,20,0);
+       vp7045_usb_op(adap->dev,FW_VERSION_READ,NULL,0,buf,20,0);
        buf[10] = '\0';
        deb_info("v%s\n",buf);
 
 /*     Dump the EEPROM */
 /*     vp7045_read_eeprom(d,buf, 255, FX2_ID_ADDR); */
 
-       d->fe = vp7045_fe_attach(d);
+       adap->fe = vp7045_fe_attach(adap->dev);
 
        return 0;
 }
 
-static struct dvb_usb_properties vp7045_properties;
+static struct dvb_usb_device_properties vp7045_properties;
 
 static int vp7045_usb_probe(struct usb_interface *intf,
                const struct usb_device_id *id)
@@ -210,24 +210,17 @@ static struct usb_device_id vp7045_usb_table [] = {
 };
 MODULE_DEVICE_TABLE(usb, vp7045_usb_table);
 
-static struct dvb_usb_properties vp7045_properties = {
-       .caps = 0,
-
+static struct dvb_usb_device_properties vp7045_properties = {
        .usb_ctrl = CYPRESS_FX2,
        .firmware = "dvb-usb-vp7045-01.fw",
 
-       .power_ctrl       = vp7045_power_ctrl,
+       .num_adapters = 1,
+       .adapter = {
+               {
        .frontend_attach  = vp7045_frontend_attach,
-       .read_mac_address = vp7045_read_mac_addr,
-
-       .rc_interval      = 400,
-       .rc_key_map       = vp7045_rc_keys,
-       .rc_key_map_size  = ARRAY_SIZE(vp7045_rc_keys),
-       .rc_query         = vp7045_rc_query,
-
        /* parameter for the MPEG2-data transfer */
-       .urb = {
-               .type = DVB_USB_BULK,
+                       .stream = {
+                               .type = USB_BULK,
                .count = 7,
                .endpoint = 0x02,
                .u = {
@@ -236,6 +229,15 @@ static struct dvb_usb_properties vp7045_properties = {
                        }
                }
        },
+               }
+       },
+       .power_ctrl       = vp7045_power_ctrl,
+       .read_mac_address = vp7045_read_mac_addr,
+
+       .rc_interval      = 400,
+       .rc_key_map       = vp7045_rc_keys,
+       .rc_key_map_size  = ARRAY_SIZE(vp7045_rc_keys),
+       .rc_query         = vp7045_rc_query,
 
        .num_device_descs = 2,
        .devices = {
index 62d69a6ea699269e2a937c1a764fd28e1cc3976c..a356d28fc3bb25af35b9b32e6ae2d0c138a1bf14 100644 (file)
@@ -553,8 +553,8 @@ static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_pa
        ndiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) / 32) & 0x1ff;
        adiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) % 32) & 0x1f;
 
-       if (adiv == 0)
-               ndiv++;
+       if (adiv == 0 && ndiv > 0)
+               ndiv--;
 
        /* control bits 11, refdiv 11, charge pump polarity 1, charge pump current, ndiv, adiv */
        state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (pump << 14) | (ndiv << 5) | adiv;
index cc28417fa33ac7fb6bc1eef2e496cd0ec682ec6e..ccc813b525d6d084217bc952a7bffe3bc2d63302 100644 (file)
@@ -37,6 +37,8 @@ struct dib3000mc_state {
 
        struct dibx000_i2c_master i2c_master;
 
+       u32 timf;
+
        fe_bandwidth_t current_bandwidth;
 
        u16 dev_id;
@@ -92,50 +94,31 @@ static int dib3000mc_identify(struct dib3000mc_state *state)
 
 static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u8 bw, u8 update_offset)
 {
-/*
-       u32 timf_msb, timf_lsb, i;
-       int tim_sgn ;
-       LUInt comp1, comp2, comp ;
-//     u32 tim_offset ;
-       comp = 27700 * BW_INDEX_TO_KHZ(bw) / 1000;
-       timf_msb = (comp >> 16) & 0x00FF;
-       timf_lsb =  comp        & 0xFFFF;
-
-       // Update the timing offset ;
-       if (update_offset) {
-               if (state->timing_offset_comp_done == 0) {
-                       usleep(200000);
-                       state->timing_offset_comp_done = 1;
-               }
-               tim_offset = dib3000mc_read_word(state, 416);
-               if ((tim_offset & 0x2000) == 0x2000)
-                       tim_offset |= 0xC000; // PB: This only works if tim_offset is s16 - weird
-
-               if (nfft == 0)
-                       tim_offset = tim_offset << 2; // PB: Do not store the offset for different things in one variable
-               state->timing_offset += tim_offset;
-       }
-       tim_offset = state->timing_offset;
+       u32 timf;
 
-       if (tim_offset < 0) {
-               tim_sgn = 1;
-               tim_offset = -tim_offset;
+       if (state->timf == 0) {
+               timf = 1384402; // default value for 8MHz
+               if (update_offset)
+                       msleep(200); // first time we do an update
        } else
-               tim_sgn = 0;
+               timf = state->timf;
 
-       comp1 = tim_offset * timf_lsb;
-       comp2 = tim_offset * timf_msb;
-       comp  = ((comp1 >> 16) + comp2) >> 7;
+       timf *= (BW_INDEX_TO_KHZ(bw) / 1000);
 
-       if (tim_sgn == 0)
-               comp = timf_msb * (1<<16) + timf_lsb + comp;
-       else
-               comp = timf_msb * (1<<16) + timf_lsb - comp;
+       if (update_offset) {
+               s16 tim_offs = dib3000mc_read_word(state, 416);
+
+               if (tim_offs &  0x2000)
+                       tim_offs -= 0x4000;
 
-       timf_msb = (comp>>16)&0xFF ;
-       timf_lsb = comp&0xFFFF;
-*/
-       u32 timf = 1384402 * (BW_INDEX_TO_KHZ(bw) / 1000);
+               if (nfft == 0)
+                       tim_offs *= 4;
+
+               timf += tim_offs;
+               state->timf = timf / (BW_INDEX_TO_KHZ(bw) / 1000);
+       }
+
+       dprintk("timf: %d\n", timf);
 
        dib3000mc_write_word(state, 23, timf >> 16);
        dib3000mc_write_word(state, 24, timf & 0xffff);
@@ -143,15 +126,18 @@ static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u8 bw,
        return 0;
 }
 
-static int dib3000mc_setup_pwm3_state(struct dib3000mc_state *state)
+static int dib3000mc_setup_pwm_state(struct dib3000mc_state *state)
 {
+       u16 reg_51, reg_52 = state->cfg->agc->setup & 0xfefb;
     if (state->cfg->pwm3_inversion) {
-               dib3000mc_write_word(state, 51, (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0));
-               dib3000mc_write_word(state, 52, (0 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | (2 << 0));
+               reg_51 =  (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
+               reg_52 |= (1 << 2);
        } else {
-               dib3000mc_write_word(state, 51, (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0));
-               dib3000mc_write_word(state, 52, (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0));
+               reg_51 = (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
+               reg_52 |= (1 << 8);
        }
+       dib3000mc_write_word(state, 51, reg_51);
+       dib3000mc_write_word(state, 52, reg_52);
 
     if (state->cfg->use_pwm3)
                dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0));
@@ -326,10 +312,10 @@ static int dib3000mc_init(struct dvb_frontend *demod)
                dib3000mc_write_word(state, 175,  0x0000);
                dib3000mc_write_word(state, 1032, 0x012C);
        }
-       dib3000mc_write_word(state, 1033, 0);
+       dib3000mc_write_word(state, 1033, 0x0000);
 
        // P_clk_cfg
-       dib3000mc_write_word(state, 1037, 12592);
+       dib3000mc_write_word(state, 1037, 0x3130);
 
        // other configurations
 
@@ -350,7 +336,7 @@ static int dib3000mc_init(struct dvb_frontend *demod)
        dib3000mc_write_word(state, 50, 0x8000);
 
        // agc setup misc
-       dib3000mc_setup_pwm3_state(state);
+       dib3000mc_setup_pwm_state(state);
 
        // P_agc_counter_lock
        dib3000mc_write_word(state, 53, 0x87);
@@ -426,10 +412,9 @@ static int dib3000mc_sleep(struct dvb_frontend *demod)
 {
        struct dib3000mc_state *state = demod->demodulator_priv;
 
-       dib3000mc_write_word(state, 1037, dib3000mc_read_word(state, 1037) | 0x0003);
        dib3000mc_write_word(state, 1031, 0xFFFF);
        dib3000mc_write_word(state, 1032, 0xFFFF);
-       dib3000mc_write_word(state, 1033, 0xFFF4);   // ****  Bin2
+       dib3000mc_write_word(state, 1033, 0xFFF0);
 
     return 0;
 }
@@ -539,6 +524,7 @@ static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dibx000
 
        reg = dib3000mc_read_word(state, 0);
        dib3000mc_write_word(state, 0, reg | (1 << 8));
+       dib3000mc_read_word(state, 511);
        dib3000mc_write_word(state, 0, reg);
 
        return 0;
@@ -578,59 +564,9 @@ static int dib3000mc_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channe
                dib3000mc_write_word(state, 33, 6);
        }
 
-       // if (lock)
-       //      dib3000mc_set_timing(state, ch->nfft, ch->Bw, 1);
-
-       return 0;
-}
-
-static int dib3000mc_demod_output_mode(struct dvb_frontend *demod, int mode)
-{
-       struct dib3000mc_state *state = demod->demodulator_priv;
-       return dib3000mc_set_output_mode(state, mode);
-}
-
-static int dib3000mc_i2c_enumeration(struct dvb_frontend *demod[], int no_of_demods, u8 default_addr)
-{
-       struct dib3000mc_state *st;
-       int k,ret=0;
-       u8 new_addr;
-
-       static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
-
-       for (k = no_of_demods-1; k >= 0; k--) {
-               st = demod[k]->demodulator_priv;
-
-               /* designated i2c address */
-               new_addr          = DIB3000MC_I2C_ADDRESS[k];
-
-               st->i2c_addr = new_addr;
-               if (dib3000mc_identify(st) != 0) {
-                       st->i2c_addr = default_addr;
-                       if (dib3000mc_identify(st) != 0) {
-                               dprintk("-E-  DiB3000P/MC #%d: not identified\n", k);
-                               return -EINVAL;
-                       }
-               }
-
-               /* turn on div_out */
-               dib3000mc_demod_output_mode(demod[k], OUTMODE_MPEG2_PAR_CONT_CLK);
-
-               // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
-               ret |= dib3000mc_write_word(st, 1024, (new_addr << 3) | 0x1);
-               st->i2c_addr = new_addr;
-       }
-
-       for (k = 0; k < no_of_demods; k++) {
-               st = demod[k]->demodulator_priv;
-
-               ret |= dib3000mc_write_word(st, 1024, st->i2c_addr << 3);
-
-               /* turn off data output */
-               dib3000mc_demod_output_mode(demod[k],OUTMODE_HIGH_Z);
-               dib3000mc_write_word(st, 769, (1 << 7) );
+       if (dib3000mc_read_word(state, 509) & 0x80)
+               dib3000mc_set_timing(state, ch->nfft, ch->Bw, 1);
 
-       }
        return 0;
 }
 
@@ -826,61 +762,79 @@ void dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg)
 }
 EXPORT_SYMBOL(dib3000mc_set_config);
 
-static struct dvb_frontend_ops dib3000mc_ops;
-
-int dib3000mc_attach(struct i2c_adapter *i2c_adap, int no_of_demods, u8        default_addr,                           u8 do_i2c_enum, struct dib3000mc_config cfg[], struct dvb_frontend *demod[])
+int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[])
 {
-       struct dib3000mc_state *st;
-       int k, num=0;
-
-       if (no_of_demods < 1)
-               return -EINVAL;
+       struct dib3000mc_state st = { .i2c_adap = i2c };
+       int k;
+       u8 new_addr;
 
-       for (k = 0; k < no_of_demods; k++) {
-               st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
-               if (st == NULL)
-                       goto error;
+       static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
 
-               num++;
+       for (k = no_of_demods-1; k >= 0; k--) {
+               st.cfg = &cfg[k];
 
-               st->cfg = &cfg[k];
-       //      st->gpio_val = cfg[k].gpio_val;
-       //      st->gpio_dir = cfg[k].gpio_dir;
-               st->i2c_adap = i2c_adap;
+               /* designated i2c address */
+               new_addr          = DIB3000MC_I2C_ADDRESS[k];
+               st.i2c_addr = new_addr;
+               if (dib3000mc_identify(&st) != 0) {
+                       st.i2c_addr = default_addr;
+                       if (dib3000mc_identify(&st) != 0) {
+                               dprintk("-E-  DiB3000P/MC #%d: not identified\n", k);
+                               return -ENODEV;
+                       }
+               }
 
-               demod[k]           = &st->demod;
-               demod[k]->demodulator_priv     = st;
-               memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
+               dib3000mc_set_output_mode(&st, OUTMODE_MPEG2_PAR_CONT_CLK);
 
-//             INIT_COMPONENT_REGISTER_ACCESS(&st->register_access, 12, 16, dib7000p_register_read, dib7000p_register_write, st);
-//             demod[k]->register_access = &st->register_access;
+               // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
+               dib3000mc_write_word(&st, 1024, (new_addr << 3) | 0x1);
+               st.i2c_addr = new_addr;
        }
 
-       if (do_i2c_enum) {
-               if (dib3000mc_i2c_enumeration(demod,no_of_demods,default_addr) != 0)
-                       goto error;
-       } else {
-               st = demod[0]->demodulator_priv;
-               st->i2c_addr = default_addr;
-               if (dib3000mc_identify(st) != 0)
-                       goto error;
-       }
+       for (k = 0; k < no_of_demods; k++) {
+               st.cfg = &cfg[k];
+               st.i2c_addr = DIB3000MC_I2C_ADDRESS[k];
 
-       for (k = 0; k < num; k++) {
-               st = demod[k]->demodulator_priv;
-               dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr);
-       }
+               dib3000mc_write_word(&st, 1024, st.i2c_addr << 3);
 
+               /* turn off data output */
+               dib3000mc_set_output_mode(&st, OUTMODE_HIGH_Z);
+       }
        return 0;
+}
+EXPORT_SYMBOL(dib3000mc_i2c_enumeration);
+
+static struct dvb_frontend_ops dib3000mc_ops;
+
+struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg)
+{
+       struct dvb_frontend *demod;
+       struct dib3000mc_state *st;
+       st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
+       if (st == NULL)
+               return NULL;
+
+       st->cfg = cfg;
+       st->i2c_adap = i2c_adap;
+       st->i2c_addr = i2c_addr;
+
+       demod                   = &st->demod;
+       demod->demodulator_priv = st;
+       memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
+
+       if (dib3000mc_identify(st) != 0)
+               goto error;
+
+       dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr);
+
+       dib3000mc_write_word(st, 1037, 0x3130);
+
+       return demod;
 
 error:
-       for (k = 0; k < num; k++) {
-               kfree(demod[k]->demodulator_priv);
-               demod[k] = NULL;
-       }
-       return -EINVAL;
+       kfree(st);
+       return NULL;
 }
-
 EXPORT_SYMBOL(dib3000mc_attach);
 
 static struct dvb_frontend_ops dib3000mc_ops = {
index fd0b2e755993be75afd64e532819080d17637668..b198cd5b18436c65890bcef1a507f3a53dc0f6fe 100644 (file)
@@ -37,17 +37,17 @@ struct dib3000mc_config {
 #define DEFAULT_DIB3000P_I2C_ADDRESS  24
 
 #if defined(CONFIG_DVB_DIB3000MC) || defined(CONFIG_DVB_DIB3000MC_MODULE)
-extern int dib3000mc_attach(struct i2c_adapter *i2c_adap, int no_of_demods, u8 default_addr,
-    u8 do_i2c_enum, struct dib3000mc_config cfg[], struct dvb_frontend *demod[]);
+extern struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg);
 #else
-static inline struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config,
-                                            struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
+static inline struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg)
 {
        printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
        return NULL;
 }
 #endif // CONFIG_DVB_DIB3000MC
 
+extern int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[]);
+
 extern struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating);
 
 extern int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff);
index 508ec1b6d1fb3af79208fb733013787e8ab0df01..450fad8d9b65099ced8ca7f99a789fce9e3636ad 100644 (file)
@@ -247,6 +247,9 @@ static void mt2060_calibrate(struct mt2060_priv *priv)
        if (mt2060_writeregs(priv,mt2060_config2,sizeof(mt2060_config2)))
                return;
 
+       /* initialize the clock output */
+       mt2060_writereg(priv, REG_VGAG, (priv->cfg->clock_out << 6) | 0x30);
+
        do {
                b |= (1 << 6); // FM1SS;
                mt2060_writereg(priv, REG_LO2C1,b);
@@ -294,13 +297,13 @@ static int mt2060_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
 static int mt2060_init(struct dvb_frontend *fe)
 {
        struct mt2060_priv *priv = fe->tuner_priv;
-       return mt2060_writereg(priv, REG_VGAG,0x33);
+       return mt2060_writereg(priv, REG_VGAG, (priv->cfg->clock_out << 6) | 0x33);
 }
 
 static int mt2060_sleep(struct dvb_frontend *fe)
 {
        struct mt2060_priv *priv = fe->tuner_priv;
-       return mt2060_writereg(priv, REG_VGAG,0x30);
+       return mt2060_writereg(priv, REG_VGAG, (priv->cfg->clock_out << 6) | 0x30);
 }
 
 static int mt2060_release(struct dvb_frontend *fe)
@@ -329,14 +332,14 @@ static const struct dvb_tuner_ops mt2060_tuner_ops = {
 };
 
 /* This functions tries to identify a MT2060 tuner by reading the PART/REV register. This is hasty. */
-int mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1)
+struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1)
 {
        struct mt2060_priv *priv = NULL;
        u8 id = 0;
 
        priv = kzalloc(sizeof(struct mt2060_priv), GFP_KERNEL);
        if (priv == NULL)
-               return -ENOMEM;
+               return NULL;
 
        priv->cfg      = cfg;
        priv->i2c      = i2c;
@@ -344,12 +347,12 @@ int mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt206
 
        if (mt2060_readreg(priv,REG_PART_REV,&id) != 0) {
                kfree(priv);
-               return -ENODEV;
+               return NULL;
        }
 
        if (id != PART_REV) {
                kfree(priv);
-               return -ENODEV;
+               return NULL;
        }
        printk(KERN_INFO "MT2060: successfully identified (IF1 = %d)\n", if1);
        memcpy(&fe->ops.tuner_ops, &mt2060_tuner_ops, sizeof(struct dvb_tuner_ops));
@@ -358,7 +361,7 @@ int mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt206
 
        mt2060_calibrate(priv);
 
-       return 0;
+       return fe;
 }
 EXPORT_SYMBOL(mt2060_attach);
 
index c58b03e823455b66c596053f6c926b13bfc7223f..34a37c2b556f01762970d40ea7869f8f8a6cd772 100644 (file)
@@ -27,9 +27,9 @@ struct i2c_adapter;
 
 struct mt2060_config {
        u8 i2c_address;
-       /* Shall we add settings for the discrete outputs ? */
+       u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */
 };
 
-extern int mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1);
+extern struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1);
 
 #endif
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 d1183c9392217666abaa9f638c071d153097058b..afb734df6e0591ac461572c9d998f670a633aac5 100644 (file)
@@ -36,7 +36,7 @@ config VIDEO_HELPER_CHIPS_AUTO
 menu "Encoders/decoders and other helper chips"
        depends on VIDEO_DEV && !VIDEO_HELPER_CHIPS_AUTO
 
-comment "Audio Decoders"
+comment "Audio decoders"
 
 config VIDEO_TVAUDIO
        tristate "Simple audio decoder chips"
@@ -51,7 +51,7 @@ config VIDEO_TVAUDIO
          module will be called tvaudio.
 
 config VIDEO_TDA7432
-       tristate "Philips TDA7432 audio processor chip"
+       tristate "Philips TDA7432 audio processor"
        depends on VIDEO_V4L1 && I2C
        ---help---
          Support for tda7432 audio decoder chip found on some bt8xx boards.
@@ -60,7 +60,7 @@ config VIDEO_TDA7432
          module will be called tda7432.
 
 config VIDEO_TDA9840
-       tristate "Philips TDA9840 audio processor chip"
+       tristate "Philips TDA9840 audio processor"
        depends on VIDEO_DEV && I2C
        ---help---
          Support for tda9840 audio decoder chip found on some Zoran boards.
@@ -69,7 +69,7 @@ config VIDEO_TDA9840
          module will be called tda9840.
 
 config VIDEO_TDA9875
-       tristate "Philips TDA9875 audio processor chip"
+       tristate "Philips TDA9875 audio processor"
        depends on VIDEO_V4L1 && I2C
        ---help---
          Support for tda9875 audio decoder chip found on some bt8xx boards.
@@ -78,7 +78,7 @@ config VIDEO_TDA9875
          module will be called tda9875.
 
 config VIDEO_TEA6415C
-       tristate "Philips TEA6415C audio processor chip"
+       tristate "Philips TEA6415C audio processor"
        depends on VIDEO_DEV && I2C
        ---help---
          Support for tea6415c audio decoder chip found on some bt8xx boards.
@@ -87,7 +87,7 @@ config VIDEO_TEA6415C
          module will be called tea6415c.
 
 config VIDEO_TEA6420
-       tristate "Philips TEA6420 audio processor chip"
+       tristate "Philips TEA6420 audio processor"
        depends on VIDEO_DEV && I2C
        ---help---
          Support for tea6420 audio decoder chip found on some bt8xx boards.
@@ -143,64 +143,10 @@ config VIDEO_WM8739
          To compile this driver as a module, choose M here: the
          module will be called wm8739.
 
-comment "MPEG video encoders"
-
-config VIDEO_CX2341X
-       tristate "Conexant CX2341x MPEG encoders"
-       depends on VIDEO_V4L2 && EXPERIMENTAL
-       ---help---
-         Support for the Conexant CX23416 MPEG encoders
-         and CX23415 MPEG encoder/decoders.
-
-         This module currently supports the encoding functions only.
-
-         To compile this driver as a module, choose M here: the
-         module will be called cx2341x.
-
-source "drivers/media/video/cx25840/Kconfig"
-
-comment "Video encoders"
-
-config VIDEO_SAA7127
-       tristate "Philips SAA7127/9 digital video encoders"
-       depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
-       ---help---
-         Support for the Philips SAA7127/9 digital video encoders.
-
-         To compile this driver as a module, choose M here: the
-         module will be called saa7127.
-
-config VIDEO_SAA7185
-       tristate "Philips SAA7185 video encoder"
-       depends on VIDEO_V4L1 && I2C
-       ---help---
-         Support for the Philips SAA7185 video encoder.
-
-         To compile this driver as a module, choose M here: the
-         module will be called saa7185.
-
-config VIDEO_ADV7170
-       tristate "Analog Devices ADV7170 video encoder driver"
-       depends on VIDEO_V4L1 && I2C
-       ---help---
-         Support for the Analog Devices ADV7170 video encoder driver
-
-         To compile this driver as a module, choose M here: the
-         module will be called adv7170.
-
-config VIDEO_ADV7175
-       tristate "Analog Devices ADV7175 video encoder driver"
-       depends on VIDEO_V4L1 && I2C
-       ---help---
-         Support for the Analog Devices ADV7175 video encoder driver
-
-         To compile this driver as a module, choose M here: the
-         module will be called adv7175.
-
 comment "Video decoders"
 
 config VIDEO_BT819
-       tristate "BT819A VideoStream Decoder"
+       tristate "BT819A VideoStream decoder"
        depends on VIDEO_V4L1 && I2C
        ---help---
          Support for BT819A video decoder.
@@ -209,7 +155,7 @@ config VIDEO_BT819
          module will be called bt819.
 
 config VIDEO_BT856
-       tristate "BT856 VideoStream Decoder"
+       tristate "BT856 VideoStream decoder"
        depends on VIDEO_V4L1 && I2C
        ---help---
          Support for BT856 video decoder.
@@ -218,7 +164,7 @@ config VIDEO_BT856
          module will be called bt856.
 
 config VIDEO_BT866
-       tristate "BT866 VideoStream Decoder"
+       tristate "BT866 VideoStream decoder"
        depends on VIDEO_V4L1 && I2C
        ---help---
          Support for BT866 video decoder.
@@ -295,7 +241,7 @@ config VIDEO_TVP5150
          module will be called tvp5150.
 
 config VIDEO_VPX3220
-       tristate "vpx3220a, vpx3216b & vpx3214c video decoder driver"
+       tristate "vpx3220a, vpx3216b & vpx3214c video decoders"
        depends on VIDEO_V4L1 && I2C
        ---help---
          Support for VPX322x video decoders.
@@ -303,6 +249,62 @@ config VIDEO_VPX3220
          To compile this driver as a module, choose M here: the
          module will be called vpx3220.
 
+comment "Video and audio decoders"
+
+source "drivers/media/video/cx25840/Kconfig"
+
+comment "MPEG video encoders"
+
+config VIDEO_CX2341X
+       tristate "Conexant CX2341x MPEG encoders"
+       depends on VIDEO_V4L2 && EXPERIMENTAL
+       ---help---
+         Support for the Conexant CX23416 MPEG encoders
+         and CX23415 MPEG encoder/decoders.
+
+         This module currently supports the encoding functions only.
+
+         To compile this driver as a module, choose M here: the
+         module will be called cx2341x.
+
+comment "Video encoders"
+
+config VIDEO_SAA7127
+       tristate "Philips SAA7127/9 digital video encoders"
+       depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+       ---help---
+         Support for the Philips SAA7127/9 digital video encoders.
+
+         To compile this driver as a module, choose M here: the
+         module will be called saa7127.
+
+config VIDEO_SAA7185
+       tristate "Philips SAA7185 video encoder"
+       depends on VIDEO_V4L1 && I2C
+       ---help---
+         Support for the Philips SAA7185 video encoder.
+
+         To compile this driver as a module, choose M here: the
+         module will be called saa7185.
+
+config VIDEO_ADV7170
+       tristate "Analog Devices ADV7170 video encoder"
+       depends on VIDEO_V4L1 && I2C
+       ---help---
+         Support for the Analog Devices ADV7170 video encoder driver
+
+         To compile this driver as a module, choose M here: the
+         module will be called adv7170.
+
+config VIDEO_ADV7175
+       tristate "Analog Devices ADV7175 video encoder"
+       depends on VIDEO_V4L1 && I2C
+       ---help---
+         Support for the Analog Devices ADV7175 video encoder driver
+
+         To compile this driver as a module, choose M here: the
+         module will be called adv7175.
+
 comment "Video improvement chips"
 
 config VIDEO_UPD64031A
@@ -351,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 d23a42b1504f907e16d7736a6771e99982a554ac..a84903e0d810233440ebfb63b549f8b0b51fae39 100644 (file)
@@ -2000,7 +2000,7 @@ struct tvcard bttv_tvcards[] = {
                .no_msp34xx     = 1,
                .no_tda9875     = 1,
                .no_tda7432     = 1,
-               .muxsel         = { 3, 0, 1, 2 },
+               .muxsel         = { 3, 1 },
                .pll            = PLL_28,
                .no_gpioirq     = 1,
                .has_dvb        = 1,
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 a7921f9d45d844d77e1a5019fe1d2f477863cfa7..46738321adafe22367e319c205adf24054fee166 100644 (file)
@@ -896,7 +896,7 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
                snprintf(name, sizeof(name), "%s/2", core->name);
                printk("%s/2: ============  START LOG STATUS  ============\n",
                       core->name);
-               cx88_call_i2c_clients(core, VIDIOC_LOG_STATUS, 0);
+               cx88_call_i2c_clients(core, VIDIOC_LOG_STATUS, NULL);
                cx2341x_log_status(&dev->params, name);
                printk("%s/2: =============  END LOG STATUS  =============\n",
                       core->name);
@@ -1086,7 +1086,7 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev,
                return -EINVAL;
 
        err = -ENODEV;
-       if (!cx88_boards[core->board].blackbird)
+       if (!(cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD))
                goto fail_core;
 
        err = -ENOMEM;
index 6214eb823b29afffc94b0da20d628846ed72c41c..af71d4225c763eefafa18907a9efd4c8c805a133 100644 (file)
@@ -294,7 +294,7 @@ struct cx88_board cx88_boards[] = {
                        .type   = CX88_RADIO,
                        .gpio0  = 0x0000bd62,
                },
-               .blackbird = 1,
+               .mpeg           = CX88_MPEG_BLACKBIRD,
        },
        [CX88_BOARD_IODATA_GVVCP3PCI] = {
                .name           = "IODATA GV-VCP3/PCI",
@@ -358,7 +358,7 @@ struct cx88_board cx88_boards[] = {
                        .type   = CX88_RADIO,
                        .gpio0  = 0x0000fde2,
                },
-               .blackbird = 1,
+               .mpeg           = CX88_MPEG_BLACKBIRD,
        },
        [CX88_BOARD_MSI_TVANYWHERE] = {
                .name           = "MSI TV-@nywhere",
@@ -401,7 +401,7 @@ struct cx88_board cx88_boards[] = {
                        .gpio0  = 0x0700,
                        .gpio2  = 0x0101,
                }},
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = {
                .name           = "DViCO FusionHDTV DVB-T1",
@@ -418,7 +418,7 @@ struct cx88_board cx88_boards[] = {
                        .vmux   = 2,
                        .gpio0  = 0x000027df,
                }},
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_KWORLD_LTV883] = {
                .name           = "KWorld LTV883RF",
@@ -488,7 +488,7 @@ struct cx88_board cx88_boards[] = {
                        .vmux   = 2,
                        .gpio0  = 0x0f00,
                }},
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_HAUPPAUGE_DVB_T1] = {
                .name           = "Hauppauge Nova-T DVB-T",
@@ -500,7 +500,7 @@ struct cx88_board cx88_boards[] = {
                        .type   = CX88_VMUX_DVB,
                        .vmux   = 0,
                }},
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_CONEXANT_DVB_T1] = {
                .name           = "Conexant DVB-T reference design",
@@ -512,7 +512,7 @@ struct cx88_board cx88_boards[] = {
                        .type   = CX88_VMUX_DVB,
                        .vmux   = 0,
                }},
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_PROVIDEO_PV259] = {
                .name           = "Provideo PV259",
@@ -524,7 +524,7 @@ struct cx88_board cx88_boards[] = {
                        .type   = CX88_VMUX_TELEVISION,
                        .vmux   = 0,
                }},
-               .blackbird = 1,
+               .mpeg           = CX88_MPEG_BLACKBIRD,
        },
        [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS] = {
                .name           = "DViCO FusionHDTV DVB-T Plus",
@@ -541,7 +541,7 @@ struct cx88_board cx88_boards[] = {
                        .vmux   = 2,
                        .gpio0  = 0x000027df,
                }},
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_DNTV_LIVE_DVB_T] = {
                .name           = "digitalnow DNTV Live! DVB-T",
@@ -560,7 +560,7 @@ struct cx88_board cx88_boards[] = {
                        .gpio0  = 0x00000700,
                        .gpio2  = 0x00000101,
                }},
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_PCHDTV_HD3000] = {
                .name           = "pcHDTV HD3000 HDTV",
@@ -599,7 +599,7 @@ struct cx88_board cx88_boards[] = {
                        .gpio2  = 0x00000000,
                        .gpio3  = 0x00000000,
                },
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_HAUPPAUGE_ROSLYN] = {
                // entry added by Kaustubh D. Bhalerao <bhalerao.1@osu.edu>
@@ -633,7 +633,7 @@ struct cx88_board cx88_boards[] = {
                         .gpio0  = 0xed96,
                         .gpio2  = 0x00ff,
                 },
-               .blackbird = 1,
+               .mpeg           = CX88_MPEG_BLACKBIRD,
        },
        [CX88_BOARD_DIGITALLOGIC_MEC] = {
                .name           = "Digital-Logic MICROSPACE Entertainment Center (MEC)",
@@ -659,7 +659,7 @@ struct cx88_board cx88_boards[] = {
                        .type   = CX88_RADIO,
                        .gpio0  = 0x00009d00,
                },
-               .blackbird = 1,
+               .mpeg           = CX88_MPEG_BLACKBIRD,
        },
        [CX88_BOARD_IODATA_GVBCTV7E] = {
                .name           = "IODATA GV/BCTV7E",
@@ -727,7 +727,7 @@ struct cx88_board cx88_boards[] = {
                        .vmux   = 2,
                        .gpio0  = 0x97e9,
                }},
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_ADSTECH_DVB_T_PCI] = {
                .name           = "ADS Tech Instant TV DVB-T PCI",
@@ -746,7 +746,7 @@ struct cx88_board cx88_boards[] = {
                        .gpio0  = 0x0700,
                        .gpio2  = 0x0101,
                }},
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1] = {
                .name           = "TerraTec Cinergy 1400 DVB-T",
@@ -755,7 +755,7 @@ struct cx88_board cx88_boards[] = {
                        .type   = CX88_VMUX_DVB,
                        .vmux   = 0,
                }},
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD] = {
                .name           = "DViCO FusionHDTV 5 Gold",
@@ -777,7 +777,7 @@ struct cx88_board cx88_boards[] = {
                        .vmux   = 2,
                        .gpio0  = 0x87f9,
                }},
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_AVERMEDIA_ULTRATV_MC_550] = {
                .name           = "AverMedia UltraTV Media Center PCI 550",
@@ -786,7 +786,7 @@ struct cx88_board cx88_boards[] = {
                .tuner_addr     = ADDR_UNSET,
                .radio_addr     = ADDR_UNSET,
                .tda9887_conf   = TDA9887_PRESENT,
-               .blackbird      = 1,
+               .mpeg           = CX88_MPEG_BLACKBIRD,
                .input          = {{
                        .type   = CX88_VMUX_COMPOSITE1,
                        .vmux   = 0,
@@ -854,7 +854,7 @@ struct cx88_board cx88_boards[] = {
                        .gpio2  = 0x00000001,
                        .gpio3  = 0x00000000,
                }},
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_WINFAST_DTV1000] = {
                .name           = "WinFast DTV1000-T",
@@ -866,7 +866,7 @@ struct cx88_board cx88_boards[] = {
                        .type   = CX88_VMUX_DVB,
                        .vmux   = 0,
                }},
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_AVERTV_303] = {
                .name           = "AVerTV 303 (M126)",
@@ -914,7 +914,7 @@ struct cx88_board cx88_boards[] = {
                        .type   = CX88_VMUX_SVIDEO,
                        .vmux   = 2,
                }},
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_HAUPPAUGE_NOVASE2_S1] = {
                .name           = "Hauppauge Nova-SE2 DVB-S",
@@ -926,7 +926,7 @@ struct cx88_board cx88_boards[] = {
                        .type   = CX88_VMUX_DVB,
                        .vmux   = 0,
                }},
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_KWORLD_DVBS_100] = {
                .name           = "KWorld DVB-S 100",
@@ -944,7 +944,7 @@ struct cx88_board cx88_boards[] = {
                        .type   = CX88_VMUX_SVIDEO,
                        .vmux   = 2,
                }},
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_HAUPPAUGE_HVR1100] = {
                .name           = "Hauppauge WinTV-HVR1100 DVB-T/Hybrid",
@@ -964,7 +964,7 @@ struct cx88_board cx88_boards[] = {
                        .vmux   = 2,
                }},
                /* fixme: Add radio support */
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_HAUPPAUGE_HVR1100LP] = {
                .name           = "Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile)",
@@ -981,7 +981,7 @@ struct cx88_board cx88_boards[] = {
                        .vmux   = 1,
                }},
                /* fixme: Add radio support */
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_DNTV_LIVE_DVB_T_PRO] = {
                .name           = "digitalnow DNTV Live! DVB-T Pro",
@@ -1008,7 +1008,7 @@ struct cx88_board cx88_boards[] = {
                         .type  = CX88_RADIO,
                         .gpio0 = 0xf80808,
                },
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_KWORLD_DVB_T_CX22702] = {
                /* Kworld V-stream Xpert DVB-T with Thomson tuner */
@@ -1030,7 +1030,7 @@ struct cx88_board cx88_boards[] = {
                        .gpio0  = 0x0700,
                        .gpio2  = 0x0101,
                }},
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL] = {
                .name           = "DViCO FusionHDTV DVB-T Dual Digital",
@@ -1047,7 +1047,7 @@ struct cx88_board cx88_boards[] = {
                        .vmux   = 2,
                        .gpio0  = 0x000067df,
                }},
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT] = {
                /* FIXME: Audio not working for s-video / composite inputs. */
@@ -1075,7 +1075,7 @@ struct cx88_board cx88_boards[] = {
                        .gpio0  = 0x3de6,
                        .gpio2  = 0x00ff,
                },
-               .blackbird      = 1,
+               .mpeg           = CX88_MPEG_BLACKBIRD,
        },
        [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID] = {
                .name           = "DViCO FusionHDTV DVB-T Hybrid",
@@ -1096,7 +1096,7 @@ struct cx88_board cx88_boards[] = {
                        .vmux   = 2,
                        .gpio0  = 0x0000a75b,
                }},
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_PCHDTV_HD5500] = {
                .name           = "pcHDTV HD5500 HDTV",
@@ -1118,7 +1118,7 @@ struct cx88_board cx88_boards[] = {
                        .vmux   = 2,
                        .gpio0  = 0x87f9,
                }},
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_KWORLD_MCE200_DELUXE] = {
                /* FIXME: tested TV input only, disabled composite,
@@ -1134,7 +1134,7 @@ struct cx88_board cx88_boards[] = {
                        .vmux   = 0,
                        .gpio0  = 0x0000BDE6
                }},
-               .blackbird = 1,
+               .mpeg           = CX88_MPEG_BLACKBIRD,
        },
        [CX88_BOARD_PIXELVIEW_PLAYTV_P7000] = {
                /* FIXME: SVideo, Composite and FM inputs are untested */
@@ -1150,7 +1150,7 @@ struct cx88_board cx88_boards[] = {
                        .vmux   = 0,
                        .gpio0  = 0x5da6,
                }},
-               .blackbird = 1,
+               .mpeg           = CX88_MPEG_BLACKBIRD,
        },
        [CX88_BOARD_NPGTECH_REALTV_TOP10FM] = {
                .name           = "NPG Tech Real TV FM Top 10",
@@ -1192,7 +1192,7 @@ struct cx88_board cx88_boards[] = {
                        .gpio2  = 0x00017304,
                        .gpio3  = 0x02000000,
                }},
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_GENIATECH_DVBS] = {
                .name          = "Geniatech DVB-S",
@@ -1207,7 +1207,7 @@ struct cx88_board cx88_boards[] = {
                        .type  = CX88_VMUX_COMPOSITE1,
                        .vmux  = 1,
                }},
-               .dvb      = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_HAUPPAUGE_HVR3000] = {
                /* FIXME: Add dvb & radio support */
@@ -1287,6 +1287,7 @@ struct cx88_board cx88_boards[] = {
                .tuner_addr     = ADDR_UNSET,
                .radio_addr     = ADDR_UNSET,
                .tda9887_conf   = TDA9887_PRESENT,
+               .audio_chip     = AUDIO_CHIP_WM8775,
                .input          = {{
                        .type   = CX88_VMUX_TELEVISION,
                        .vmux   = 0,
@@ -1301,7 +1302,7 @@ struct cx88_board cx88_boards[] = {
                        .gpio0  = 0xe780,
                }},
                /* fixme: Add radio support */
-               .dvb            = 1,
+               .mpeg           = CX88_MPEG_DVB,
        },
 };
 const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
@@ -1581,6 +1582,14 @@ struct cx88_subid cx88_subids[] = {
                .subvendor = 0x107d,
                .subdevice = 0x6632,
                .card      = CX88_BOARD_LEADTEK_PVR2000,
+       },{
+               .subvendor = 0x12ab,
+               .subdevice = 0x2300, /* Club3D Zap TV2100 */
+               .card      = CX88_BOARD_KWORLD_DVB_T_CX22702,
+       },{
+               .subvendor = 0x0070,
+               .subdevice = 0x9000,
+               .card      = CX88_BOARD_HAUPPAUGE_DVB_T1,
        },
 };
 const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
index f379ede3049a5cfce78002b62f83346b9e72e52c..4b655f2ef27880038222e9795302887571325086 100644 (file)
@@ -658,13 +658,6 @@ static unsigned int inline norm_fsc8(struct cx88_tvnorm *norm)
        return (norm->id & V4L2_STD_625_50) ? pal : ntsc;
 }
 
-static unsigned int inline norm_notchfilter(struct cx88_tvnorm *norm)
-{
-       return (norm->id & V4L2_STD_625_50)
-               ? HLNotchFilter135PAL
-               : HLNotchFilter135NTSC;
-}
-
 static unsigned int inline norm_htotal(struct cx88_tvnorm *norm)
 {
        /* Should always be Line Draw Time / (4*FSC) */
@@ -937,7 +930,7 @@ int cx88_set_tvnorm(struct cx88_core *core, struct cx88_tvnorm *norm)
        // htotal
        tmp64 = norm_htotal(norm) * (u64)vdec_clock;
        do_div(tmp64, fsc8);
-       htotal = (u32)tmp64 | (norm_notchfilter(norm) << 11);
+       htotal = (u32)tmp64 | (HLNotchFilter4xFsc << 11);
        dprintk(1,"set_tvnorm: MO_HTOTAL        0x%08x [old=0x%08x,htotal=%d]\n",
                htotal, cx_read(MO_HTOTAL), (u32)tmp64);
        cx_write(MO_HTOTAL, htotal);
index c87041dee21e7d677b835fdc6683da01e1a110ef..bd0c8797f26d6289898dcf1de0e5480a4b02c7b6 100644 (file)
@@ -802,7 +802,7 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev,
                return -EINVAL;
 
        err = -ENODEV;
-       if (!cx88_boards[core->board].dvb)
+       if (!(cx88_boards[core->board].mpeg & CX88_MPEG_DVB))
                goto fail_core;
 
        err = -ENOMEM;
index 27b5dbb2ca1a12d5ddb33a6249987f6f4947ea7a..88af23a938702335697fb18bb1ce33526fa79dad 100644 (file)
@@ -145,7 +145,7 @@ void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg)
        if (0 != core->i2c_rc)
                return;
 
-       if (core->dvbdev) {
+       if ( (core->dvbdev) && (core->dvbdev->dvb.frontend) ) {
                if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl)
                        core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1);
 
@@ -220,7 +220,7 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
 
        if (core->tuner_type != TUNER_ABSENT)
                core->i2c_adap.class |= I2C_CLASS_TV_ANALOG;
-       if (cx88_boards[core->board].dvb)
+       if (cx88_boards[core->board].mpeg & CX88_MPEG_DVB)
                core->i2c_adap.class |= I2C_CLASS_TV_DIGITAL;
 
        core->i2c_adap.dev.parent = &pci->dev;
index 138a4f692501786bcda6227baf75a62e20c84120..d6d980774c21bbbe20491f9a1d4c18a2488dfb3f 100644 (file)
@@ -65,8 +65,17 @@ static int cx8802_start_dma(struct cx8802_dev    *dev,
 
        /* FIXME: this needs a review.
         * also: move to cx88-blackbird + cx88-dvb source files? */
+       if (cx88_boards[core->board].mpeg == (CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD) ) {
+               /* Report a warning until the mini driver patch is applied,
+                * else the following conditions will set the dma registers incorrectly.
+                * This will be removed in the next major patch and changes to the conditions
+                * will be made.
+                */
+               printk(KERN_INFO "%s() board->(CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD) is invalid\n", __FUNCTION__);
+               return -EINVAL;
+       }
 
-       if (cx88_boards[core->board].dvb) {
+       if (cx88_boards[core->board].mpeg & CX88_MPEG_DVB) {
                /* negedge driven & software reset */
                cx_write(TS_GEN_CNTRL, 0x0040 | dev->ts_gen_cntrl);
                udelay(100);
@@ -92,7 +101,7 @@ static int cx8802_start_dma(struct cx8802_dev    *dev,
                udelay(100);
        }
 
-       if (cx88_boards[core->board].blackbird) {
+       if (cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD) {
                cx_write(MO_PINMUX_IO, 0x88); /* enable MPEG parallel IO */
 
                cx_write(TS_GEN_CNTRL, 0x46); /* punctured clock TS & posedge driven & software reset */
index 741e7c5e69ec7085d2d68cb53f05dddef74ad9e1..58ba9f773524605833a7bdc0b6267ba149b0d025 100644 (file)
@@ -142,7 +142,7 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl)
        cx_write(AUD_RATE_THRES_DMD, 0x000000C0);
        cx88_start_audio_dma(core);
 
-       if (cx88_boards[core->board].blackbird) {
+       if (cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD) {
                /* sets sound input from external adc */
                switch (core->board) {
                case CX88_BOARD_HAUPPAUGE_ROSLYN:
@@ -164,7 +164,7 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl)
                cx_write(AUD_I2SCNTL, 0);
                /* cx_write(AUD_APB_IN_RATE_ADJ, 0); */
        }
-       if ((always_analog) || (!cx88_boards[core->board].blackbird)) {
+       if ((always_analog) || (!(cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD))) {
                ctl |= EN_DAC_ENABLE;
                cx_write(AUD_CTL, ctl);
        }
index fbc79e9842aa70299c2d4b98147805eaffdc2996..cb0c0eea20f956e392ddfac737e87116e1f4b0f6 100644 (file)
@@ -1928,6 +1928,9 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
        if (TUNER_ABSENT != core->tuner_type)
                request_module("tuner");
 
+       if (cx88_boards[ core->board ].audio_chip == AUDIO_CHIP_WM8775)
+               request_module("wm8775");
+
        /* register v4l devices */
        dev->video_dev = cx88_vdev_init(core,dev->pci,
                                        &cx8800_video_template,"video");
index 89f12e273b7f83a5ac7f47e241028e321f9dd839..3bc91aad4fe5df80b4d3d9bcea67ce3807b71462 100644 (file)
@@ -30,6 +30,7 @@
 #include <media/tveeprom.h>
 #include <media/video-buf.h>
 #include <media/cx2341x.h>
+#include <media/audiochip.h>
 #include <media/video-buf-dvb.h>
 
 #include "btcx-risc.h"
 #include <linux/mutex.h>
 #define CX88_VERSION_CODE KERNEL_VERSION(0,0,6)
 
-#ifndef TRUE
-# define TRUE (1==1)
-#endif
-#ifndef FALSE
-# define FALSE (1==0)
-#endif
 #define UNSET (-1U)
 
 #define CX88_MAXBOARDS 8
@@ -73,6 +68,12 @@ enum cx88_deemph_type {
        FM_DEEMPH_75
 };
 
+enum cx88_board_type {
+       CX88_BOARD_NONE = 0,
+       CX88_MPEG_DVB,
+       CX88_MPEG_BLACKBIRD
+};
+
 /* ----------------------------------------------------------- */
 /* tv norms                                                    */
 
@@ -230,8 +231,8 @@ struct cx88_board {
        int                     tda9887_conf;
        struct cx88_input       input[MAX_CX88_INPUT];
        struct cx88_input       radio;
-       unsigned int            blackbird:1;
-       unsigned int            dvb:1;
+       enum cx88_board_type    mpeg;
+       enum audiochip          audio_chip;
 };
 
 struct cx88_subid {
index fba30a40e9c6fface92fe3909314e64fefd39057..1457b1602221d9d9d430ae3445c5314dd6472a97 100644 (file)
@@ -64,23 +64,32 @@ MODULE_PARM_DESC(hauppauge, "Specify Hauppauge remote: 0=black, 1=grey (defaults
 static int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
 {
        unsigned char buf[3];
-       int start, toggle, dev, code;
+       int start, range, toggle, dev, code;
 
        /* poll IR chip */
        if (3 != i2c_master_recv(&ir->c,buf,3))
                return -EIO;
 
        /* split rc5 data block ... */
-       start  = (buf[0] >> 6) &    3;
+       start  = (buf[0] >> 7) &    1;
+       range  = (buf[0] >> 6) &    1;
        toggle = (buf[0] >> 5) &    1;
        dev    =  buf[0]       & 0x1f;
        code   = (buf[1] >> 2) & 0x3f;
 
-       if (3 != start)
+       /* rc5 has two start bits
+        * the first bit must be one
+        * the second bit defines the command range (1 = 0-63, 0 = 64 - 127)
+        */
+       if (!start)
                /* no key pressed */
                return 0;
-       dprintk(1,"ir hauppauge (rc5): s%d t%d dev=%d code=%d\n",
-               start, toggle, dev, code);
+
+       if (!range)
+               code += 64;
+
+       dprintk(1,"ir hauppauge (rc5): s%d r%d t%d dev=%d code=%d\n",
+               start, range, toggle, dev, code);
 
        /* return key */
        *ir_key = code;
index 56246b8578f32039d68c7098d70598b33fe7db1f..cf43df3fe708c8eeba0fb4da03ab61b2fe5f7f7d 100644 (file)
@@ -904,6 +904,8 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind)
        state->has_virtual_dolby_surround = msp_revision == 'G' && msp_prod_lo == 1;
        /* Has Virtual Dolby Surround & Dolby Pro Logic: only in msp34x2 */
        state->has_dolby_pro_logic = msp_revision == 'G' && msp_prod_lo == 2;
+       /* The msp343xG supports BTSC only and cannot do Automatic Standard Detection. */
+       state->force_btsc = msp_family == 3 && msp_revision == 'G' && msp_prod_hi == 3;
 
        state->opmode = opmode;
        if (state->opmode == OPMODE_AUTO) {
index 545e4ac094f2e2dd513a275a8a730db4fdbe83bb..7531efa1615e726d57ece12fbe11cb35e0fa3bf5 100644 (file)
@@ -64,6 +64,7 @@ struct msp_state {
        u8 has_sound_processing;
        u8 has_virtual_dolby_surround;
        u8 has_dolby_pro_logic;
+       u8 force_btsc;
 
        int radio;
        int opmode;
index ed02ff81138865c27b7b28a80a455af34aae313d..4c7f85b566a0ad222013e3f1871f4973e76dc859 100644 (file)
@@ -960,9 +960,10 @@ int msp34xxg_thread(void *data)
 
                /* setup the chip*/
                msp34xxg_reset(client);
-               state->std = state->radio ? 0x40 : msp_standard;
-               /* start autodetect */
+               state->std = state->radio ? 0x40 :
+                       (state->force_btsc && msp_standard == 1) ? 32 : msp_standard;
                msp_write_dem(client, 0x20, state->std);
+               /* start autodetect */
                if (state->std != 1)
                        goto unmute;
 
index a52171ef6134ca6bf77c1c82f3f972e65209e9e5..5645c9318890d6c701f3bfb9aed7729830fa42fb 100644 (file)
@@ -18,8 +18,8 @@ config VIDEO_PVRUSB2_29XXX
        select VIDEO_SAA711X
        select VIDEO_MSP3400
        ---help---
-         This option enables support for WinTV-PVR USB2 devices whose 
-         model number is of the form "29xxx" (leading prefix of "29" 
+         This option enables support for WinTV-PVR USB2 devices whose
+         model number is of the form "29xxx" (leading prefix of "29"
          followed by 3 digits).
          To see if you may need this option, examine the white
          sticker on the underside of your device.
@@ -37,14 +37,9 @@ config VIDEO_PVRUSB2_24XXX
          form "24xxx" (leading prefix of "24" followed by 3 digits).
          To see if you may need this option, examine the white
          sticker on the underside of your device.  Enabling this
-         option will not harm support for older devices, however it
-         is a separate option because of the experimental nature of
-         this new feature.
+         option will not harm support for older devices.
 
-         If you are in doubt, say N.
-
-         Note: This feature is _very_ experimental.  You have been
-         warned.
+         If you are in doubt, say Y.
 
 config VIDEO_PVRUSB2_SYSFS
        bool "pvrusb2 sysfs support (EXPERIMENTAL)"
index 88604365777c32c936bec578935ce3337ceb2dd5..3d8cd0daf6a9314d1dbc1a37194a57d7a05ac510 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/slab.h>
 #include <linux/firmware.h>
 #include <linux/videodev2.h>
+#include <media/v4l2-common.h>
 #include <asm/semaphore.h>
 #include "pvrusb2.h"
 #include "pvrusb2-std.h"
@@ -3131,6 +3132,42 @@ static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw)
 }
 
 
+int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
+                            u32 chip_id,unsigned long reg_id,
+                            int setFl,u32 *val_ptr)
+{
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+       struct list_head *item;
+       struct pvr2_i2c_client *cp;
+       struct v4l2_register req;
+       int stat = 0;
+       int okFl = 0;
+
+       req.i2c_id = chip_id;
+       req.reg = reg_id;
+       if (setFl) req.val = *val_ptr;
+       mutex_lock(&hdw->i2c_list_lock); do {
+               list_for_each(item,&hdw->i2c_clients) {
+                       cp = list_entry(item,struct pvr2_i2c_client,list);
+                       if (cp->client->driver->id != chip_id) continue;
+                       stat = pvr2_i2c_client_cmd(
+                               cp,(setFl ? VIDIOC_INT_S_REGISTER :
+                                   VIDIOC_INT_G_REGISTER),&req);
+                       if (!setFl) *val_ptr = req.val;
+                       okFl = !0;
+                       break;
+               }
+       } while (0); mutex_unlock(&hdw->i2c_list_lock);
+       if (okFl) {
+               return stat;
+       }
+       return -EINVAL;
+#else
+       return -ENOSYS;
+#endif
+}
+
+
 /*
   Stuff for Emacs to see, in order to encourage consistent editing style:
   *** Local Variables: ***
index fd931b5da490b4bc66c8538923ac80eb98cd118a..29979bb2a7689fd3d43bb9d2f5634ade6fb4c1c1 100644 (file)
@@ -211,6 +211,14 @@ int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *);
 /* Store the v4l minor device number */
 void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *,int);
 
+/* Direct read/write access to chip's registers:
+   chip_id - unique id of chip (e.g. I2C_DRIVERD_xxxx)
+   reg_id  - register number to access
+   setFl   - true to set the register, false to read it
+   val_ptr - storage location for source / result. */
+int pvr2_hdw_register_access(struct pvr2_hdw *,
+                            u32 chip_id,unsigned long reg_id,
+                            int setFl,u32 *val_ptr);
 
 /* The following entry points are all lower level things you normally don't
    want to worry about. */
index ed3e8105292a23b807c5267e1216ab851d524821..05121666b9ba5c6a516dcf76023c7a4602ac8401 100644 (file)
@@ -19,6 +19,7 @@
  *
  */
 
+#include <linux/kernel.h>
 #include "pvrusb2-i2c-core.h"
 #include "pvrusb2-hdw-internal.h"
 #include "pvrusb2-debug.h"
@@ -89,7 +90,8 @@ void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
 
 const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx)
 {
-       if (idx >= sizeof(ops)/sizeof(ops[0])) return 0;
+       if (idx >= ARRAY_SIZE(ops))
+               return NULL;
        return ops[idx];
 }
 
index 3608c2f81df912fa91a6bc33a7db57691d452cd9..97e974d9b9c34ba8b215f0a61eb9a04f96e34008 100644 (file)
 #include "pvrusb2-v4l2.h"
 #include "pvrusb2-ioread.h"
 #include <linux/videodev2.h>
+#include <media/v4l2-dev.h>
 #include <media/v4l2-common.h>
 
 struct pvr2_v4l2_dev;
 struct pvr2_v4l2_fh;
 struct pvr2_v4l2;
 
-/* V4L no longer provide the ability to set / get a private context pointer
-   (i.e. video_get_drvdata / video_set_drvdata), which means we have to
-   concoct our own context locating mechanism.  Supposedly this is intended
-   to simplify driver implementation.  It's not clear to me how that can
-   possibly be true.  Our solution here is to maintain a lookup table of
-   our context instances, indexed by the minor device number of the V4L
-   device.  See pvr2_v4l2_open() for some implications of this approach. */
-static struct pvr2_v4l2_dev *devices[256];
-static DEFINE_MUTEX(device_lock);
-
 struct pvr2_v4l2_dev {
+       struct video_device devbase; /* MUST be first! */
        struct pvr2_v4l2 *v4lp;
-       struct video_device *vdev;
        struct pvr2_context_stream *stream;
-       int ctxt_idx;
        enum pvr2_config config;
 };
 
@@ -74,7 +64,7 @@ struct pvr2_v4l2 {
        struct v4l2_prio_state prio;
 
        /* streams */
-       struct pvr2_v4l2_dev video_dev;
+       struct pvr2_v4l2_dev *vdev;
 };
 
 static int video_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
@@ -671,6 +661,20 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
                ret = 0;
                break;
        }
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+       case VIDIOC_INT_G_REGISTER:
+       case VIDIOC_INT_S_REGISTER:
+       {
+               u32 val;
+               struct v4l2_register *req = (struct v4l2_register *)arg;
+               if (cmd == VIDIOC_INT_S_REGISTER) val = req->val;
+               ret = pvr2_hdw_register_access(
+                       hdw,req->i2c_id,req->reg,
+                       cmd == VIDIOC_INT_S_REGISTER,&val);
+               if (cmd == VIDIOC_INT_G_REGISTER) req->val = val;
+               break;
+       }
+#endif
 
        default :
                ret = v4l_compat_translate_ioctl(inode,file,cmd,
@@ -704,21 +708,22 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
 static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
 {
        printk(KERN_INFO "pvrusb2: unregistering device video%d [%s]\n",
-              dip->vdev->minor,pvr2_config_get_name(dip->config));
-       if (dip->ctxt_idx >= 0) {
-               mutex_lock(&device_lock);
-               devices[dip->ctxt_idx] = NULL;
-               dip->ctxt_idx = -1;
-               mutex_unlock(&device_lock);
-       }
-       video_unregister_device(dip->vdev);
+              dip->devbase.minor,pvr2_config_get_name(dip->config));
+
+       /* Paranoia */
+       dip->v4lp = 0;
+       dip->stream = 0;
+
+       /* Actual deallocation happens later when all internal references
+          are gone. */
+       video_unregister_device(&dip->devbase);
 }
 
 
 static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp)
 {
        pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,-1);
-       pvr2_v4l2_dev_destroy(&vp->video_dev);
+       pvr2_v4l2_dev_destroy(vp->vdev);
 
        pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp);
        pvr2_channel_done(&vp->channel);
@@ -726,6 +731,14 @@ static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp)
 }
 
 
+static void pvr2_video_device_release(struct video_device *vdev)
+{
+       struct pvr2_v4l2_dev *dev;
+       dev = container_of(vdev,struct pvr2_v4l2_dev,devbase);
+       kfree(dev);
+}
+
+
 static void pvr2_v4l2_internal_check(struct pvr2_channel *chp)
 {
        struct pvr2_v4l2 *vp;
@@ -797,40 +810,12 @@ static int pvr2_v4l2_release(struct inode *inode, struct file *file)
 
 static int pvr2_v4l2_open(struct inode *inode, struct file *file)
 {
-       struct pvr2_v4l2_dev *dip = NULL; /* Our own context pointer */
+       struct pvr2_v4l2_dev *dip; /* Our own context pointer */
        struct pvr2_v4l2_fh *fhp;
        struct pvr2_v4l2 *vp;
        struct pvr2_hdw *hdw;
 
-       mutex_lock(&device_lock);
-       /* MCI 7-Jun-2006 Even though we're just doing what amounts to an
-          atomic read of the device mapping array here, we still need the
-          mutex.  The problem is that there is a tiny race possible when
-          we register the device.  We can't update the device mapping
-          array until after the device has been registered, owing to the
-          fact that we can't know the minor device number until after the
-          registration succeeds.  And if another thread tries to open the
-          device in the window of time after registration but before the
-          map is updated, then it will get back an erroneous null pointer
-          and the open will result in a spurious failure.  The only way to
-          prevent that is to (a) be inside the mutex here before we access
-          the array, and (b) cover the entire registration process later
-          on with this same mutex.  Thus if we get inside the mutex here,
-          then we can be assured that the registration process actually
-          completed correctly.  This is an unhappy complication from the
-          use of global data in a driver that lives in a preemptible
-          environment.  It sure would be nice if the video device itself
-          had a means for storing and retrieving a local context pointer.
-          Oh wait.  It did.  But now it's gone.  Silly me. */
-       {
-               unsigned int midx = iminor(file->f_dentry->d_inode);
-               if (midx < sizeof(devices)/sizeof(devices[0])) {
-                       dip = devices[midx];
-               }
-       }
-       mutex_unlock(&device_lock);
-
-       if (!dip) return -ENODEV; /* Should be impossible but I'm paranoid */
+       dip = container_of(video_devdata(file),struct pvr2_v4l2_dev,devbase);
 
        vp = dip->v4lp;
        hdw = vp->channel.hdw;
@@ -1060,38 +1045,24 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
                return;
        }
 
-       dip->vdev = video_device_alloc();
-       if (!dip->vdev) {
-               err("Alloc of pvrusb2 v4l video device failed");
-               return;
-       }
-
-       memcpy(dip->vdev,&vdev_template,sizeof(vdev_template));
-       dip->vdev->release = video_device_release;
-       mutex_lock(&device_lock);
+       memcpy(&dip->devbase,&vdev_template,sizeof(vdev_template));
+       dip->devbase.release = pvr2_video_device_release;
 
        mindevnum = -1;
        unit_number = pvr2_hdw_get_unit_number(vp->channel.mc_head->hdw);
        if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
                mindevnum = video_nr[unit_number];
        }
-       if ((video_register_device(dip->vdev, v4l_type, mindevnum) < 0) &&
-           (video_register_device(dip->vdev, v4l_type, -1) < 0)) {
+       if ((video_register_device(&dip->devbase, v4l_type, mindevnum) < 0) &&
+           (video_register_device(&dip->devbase, v4l_type, -1) < 0)) {
                err("Failed to register pvrusb2 v4l video device");
        } else {
                printk(KERN_INFO "pvrusb2: registered device video%d [%s]\n",
-                      dip->vdev->minor,pvr2_config_get_name(dip->config));
-       }
-
-       if ((dip->vdev->minor < sizeof(devices)/sizeof(devices[0])) &&
-           (devices[dip->vdev->minor] == NULL)) {
-               dip->ctxt_idx = dip->vdev->minor;
-               devices[dip->ctxt_idx] = dip;
+                      dip->devbase.minor,pvr2_config_get_name(dip->config));
        }
-       mutex_unlock(&device_lock);
 
        pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,
-                                       dip->vdev->minor);
+                                       dip->devbase.minor);
 }
 
 
@@ -1102,15 +1073,19 @@ struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp)
        vp = kmalloc(sizeof(*vp),GFP_KERNEL);
        if (!vp) return vp;
        memset(vp,0,sizeof(*vp));
-       vp->video_dev.ctxt_idx = -1;
+       vp->vdev = kmalloc(sizeof(*vp->vdev),GFP_KERNEL);
+       if (!vp->vdev) {
+               kfree(vp);
+               return 0;
+       }
+       memset(vp->vdev,0,sizeof(*vp->vdev));
        pvr2_channel_init(&vp->channel,mnp);
        pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp);
 
        vp->channel.check_func = pvr2_v4l2_internal_check;
 
        /* register streams */
-       pvr2_v4l2_dev_init(&vp->video_dev,vp,pvr2_config_mpeg);
-
+       pvr2_v4l2_dev_init(vp->vdev,vp,pvr2_config_mpeg);
 
        return vp;
 }
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 aa1db509f3d477ec895a42c33a90b21ebe976787..fe3c83ca3de3b2af716c64e5afc3d1cd35e17911 100644 (file)
@@ -2965,6 +2965,35 @@ struct saa7134_board saa7134_boards[] = {
                        .amux = LINE1,
                },
        },
+       [SAA7134_BOARD_AVERMEDIA_A16AR] = {
+               /* Petr Baudis <pasky@ucw.cz> */
+               .name           = "AVerMedia TV Hybrid A16AR",
+               .audio_clock    = 0x187de7,
+               .tuner_type     = TUNER_PHILIPS_TDA8290, /* untested */
+               .radio_type     = TUNER_TEA5767, /* untested */
+               .tuner_addr     = ADDR_UNSET,
+               .radio_addr     = ADDR_UNSET,
+               .tda9887_conf   = TDA9887_PRESENT,
+               .mpeg           = SAA7134_MPEG_DVB,
+               .inputs         = {{
+                       .name = name_tv,
+                       .vmux = 1,
+                       .amux = TV,
+                       .tv   = 1,
+               },{
+                       .name = name_comp1,
+                       .vmux = 3,
+                       .amux = LINE2,
+               },{
+                       .name = name_svideo,
+                       .vmux = 8,
+                       .amux = LINE1,
+               }},
+               .radio = {
+                       .name = name_radio,
+                       .amux = LINE1,
+               },
+       },
 };
 
 const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -3561,6 +3590,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
                .subvendor    = 0x0919, /* Philips Proteus PRO 2309 */
                .subdevice    = 0x2003,
                .driver_data  = SAA7134_BOARD_PROTEUS_2309,
+       },{
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+               .subvendor    = 0x1461,
+               .subdevice    = 0x2c00,
+               .driver_data  = SAA7134_BOARD_AVERMEDIA_A16AR,
        },{
                /* --- boards without eeprom + subsystem ID --- */
                .vendor       = PCI_VENDOR_ID_PHILIPS,
@@ -3703,6 +3738,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
                saa_writeb(SAA7134_GPIO_GPMODE3, 0x08);
                saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x00);
                break;
+       case SAA7134_BOARD_AVERMEDIA_A16AR:
        case SAA7134_BOARD_AVERMEDIA_CARDBUS:
                /* power-up tuner chip */
                saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0xffffffff, 0xffffffff);
index b6881541e704ab0192834af210a33d2594009d2e..fb741fa465a500effd4dd193f7aad4175309340c 100644 (file)
@@ -1055,6 +1055,7 @@ static int dvb_init(struct saa7134_dev *dev)
                }
                break;
        case SAA7134_BOARD_AVERMEDIA_777:
+       case SAA7134_BOARD_AVERMEDIA_A16AR:
                printk("%s: avertv 777 dvb setup\n",dev->name);
                dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777,
                                               &dev->i2c_adap);
index f7ea857d5d73e540eda9913bab293de9450b5d7a..ff5991136f4ec409b0c5ecd03b7dcfbe957fde9d 100644 (file)
@@ -185,6 +185,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
        case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
        case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
        case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
+       case SAA7134_BOARD_AVERMEDIA_A16AR:
                ir_codes     = ir_codes_avermedia;
                mask_keycode = 0x0007C8;
                mask_keydown = 0x000010;
index 7db7b970595388865d3374918b2c3d7ae0a17a34..701a90942108d2946c8e04b6e4336923713b95a8 100644 (file)
@@ -226,6 +226,7 @@ struct saa7134_format {
 #define SAA7134_BOARD_MEDION_MD8800_QUADRO 96
 #define SAA7134_BOARD_FLYDVBS_LR300 97
 #define SAA7134_BOARD_PROTEUS_2309 98
+#define SAA7134_BOARD_AVERMEDIA_A16AR   99
 
 #define SAA7134_MAXBOARDS 8
 #define SAA7134_INPUT_MAX 8
index acc5ea936687a02ed7b52b049b2c894a828daa74..f429f49901b9a0394980f1aea61f2715eb9ddc63 100644 (file)
@@ -365,7 +365,12 @@ videobuf_iolock(struct videobuf_queue* q, struct videobuf_buffer *vb,
                if (NULL == fbuf)
                        return -EINVAL;
                /* FIXME: need sanity checks for vb->boff */
-               bus   = (dma_addr_t)fbuf->base + vb->boff;
+               /*
+                * Using a double cast to avoid compiler warnings when
+                * building for PAE. Compiler doesn't like direct casting
+                * of a 32 bit ptr to 64 bit integer.
+                */
+               bus   = (dma_addr_t)(unsigned long)fbuf->base + vb->boff;
                pages = PAGE_ALIGN(vb->size) >> PAGE_SHIFT;
                err = videobuf_dma_init_overlay(&vb->dma,PCI_DMA_FROMDEVICE,
                                                bus, pages);
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 19c2b85249c3029556e532117394f65d611ce0f8..d65ece76095a43283de2714a8c7dc0ac9a0f1625 100644 (file)
@@ -3,5 +3,8 @@
 #
 obj- := misc.o # Dummy rule to force built-in.o to be made
 
-obj-$(CONFIG_IBM_ASM)  += ibmasm/
+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/lkdtm.c b/drivers/misc/lkdtm.c
new file mode 100644 (file)
index 0000000..e689ee9
--- /dev/null
@@ -0,0 +1,342 @@
+/*
+ * Kprobe module for testing crash dumps
+ *
+ * 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: Ankita Garg <ankita@in.ibm.com>
+ *
+ * This module induces system failures at predefined crashpoints to
+ * evaluate the reliability of crash dumps obtained using different dumping
+ * solutions.
+ *
+ * It is adapted from the Linux Kernel Dump Test Tool by
+ * Fernando Luis Vazquez Cao <http://lkdtt.sourceforge.net>
+ *
+ * Usage :  insmod lkdtm.ko [recur_count={>0}] cpoint_name=<> cpoint_type=<>
+ *                                                     [cpoint_count={>0}]
+ *
+ * recur_count : Recursion level for the stack overflow test. Default is 10.
+ *
+ * cpoint_name : Crash point where the kernel is to be crashed. It can be
+ *              one of INT_HARDWARE_ENTRY, INT_HW_IRQ_EN, INT_TASKLET_ENTRY,
+ *              FS_DEVRW, MEM_SWAPOUT, TIMERADD, SCSI_DISPATCH_CMD,
+ *              IDE_CORE_CP
+ *
+ * cpoint_type : Indicates the action to be taken on hitting the crash point.
+ *              It can be one of PANIC, BUG, EXCEPTION, LOOP, OVERFLOW
+ *
+ * cpoint_count : Indicates the number of times the crash point is to be hit
+ *               to trigger an action. The default is 10.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/kprobes.h>
+#include <linux/kallsyms.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <scsi/scsi_cmnd.h>
+
+#ifdef CONFIG_IDE
+#include <linux/ide.h>
+#endif
+
+#define NUM_CPOINTS 8
+#define NUM_CPOINT_TYPES 5
+#define DEFAULT_COUNT 10
+#define REC_NUM_DEFAULT 10
+
+enum cname {
+       INVALID,
+       INT_HARDWARE_ENTRY,
+       INT_HW_IRQ_EN,
+       INT_TASKLET_ENTRY,
+       FS_DEVRW,
+       MEM_SWAPOUT,
+       TIMERADD,
+       SCSI_DISPATCH_CMD,
+       IDE_CORE_CP
+};
+
+enum ctype {
+       NONE,
+       PANIC,
+       BUG,
+       EXCEPTION,
+       LOOP,
+       OVERFLOW
+};
+
+static char* cp_name[] = {
+       "INT_HARDWARE_ENTRY",
+       "INT_HW_IRQ_EN",
+       "INT_TASKLET_ENTRY",
+       "FS_DEVRW",
+       "MEM_SWAPOUT",
+       "TIMERADD",
+       "SCSI_DISPATCH_CMD",
+       "IDE_CORE_CP"
+};
+
+static char* cp_type[] = {
+       "PANIC",
+       "BUG",
+       "EXCEPTION",
+       "LOOP",
+       "OVERFLOW"
+};
+
+static struct jprobe lkdtm;
+
+static int lkdtm_parse_commandline(void);
+static void lkdtm_handler(void);
+
+static char* cpoint_name = INVALID;
+static char* cpoint_type = NONE;
+static int cpoint_count = DEFAULT_COUNT;
+static int recur_count = REC_NUM_DEFAULT;
+
+static enum cname cpoint = INVALID;
+static enum ctype cptype = NONE;
+static int count = DEFAULT_COUNT;
+
+module_param(recur_count, int, 0644);
+MODULE_PARM_DESC(recur_count, "Recurcion level for the stack overflow test,\
+                                default is 10");
+module_param(cpoint_name, charp, 0644);
+MODULE_PARM_DESC(cpoint_name, "Crash Point, where kernel is to be crashed");
+module_param(cpoint_type, charp, 06444);
+MODULE_PARM_DESC(cpoint_type, "Crash Point Type, action to be taken on\
+                               hitting the crash point");
+module_param(cpoint_count, int, 06444);
+MODULE_PARM_DESC(cpoint_count, "Crash Point Count, number of times the \
+                               crash point is to be hit to trigger action");
+
+unsigned int jp_do_irq(unsigned int irq, struct pt_regs *regs)
+{
+       lkdtm_handler();
+       jprobe_return();
+       return 0;
+}
+
+irqreturn_t jp_handle_irq_event(unsigned int irq, struct pt_regs *regs,
+                       struct irqaction *action)
+{
+       lkdtm_handler();
+       jprobe_return();
+       return 0;
+}
+
+void jp_tasklet_action(struct softirq_action *a)
+{
+       lkdtm_handler();
+       jprobe_return();
+}
+
+void jp_ll_rw_block(int rw, int nr, struct buffer_head *bhs[])
+{
+       lkdtm_handler();
+       jprobe_return();
+}
+
+struct scan_control;
+
+unsigned long jp_shrink_page_list(struct list_head *page_list,
+                                        struct scan_control *sc)
+{
+       lkdtm_handler();
+       jprobe_return();
+       return 0;
+}
+
+int jp_hrtimer_start(struct hrtimer *timer, ktime_t tim,
+                               const enum hrtimer_mode mode)
+{
+       lkdtm_handler();
+       jprobe_return();
+       return 0;
+}
+
+int jp_scsi_dispatch_cmd(struct scsi_cmnd *cmd)
+{
+       lkdtm_handler();
+       jprobe_return();
+       return 0;
+}
+
+#ifdef CONFIG_IDE
+int jp_generic_ide_ioctl(ide_drive_t *drive, struct file *file,
+                       struct block_device *bdev, unsigned int cmd,
+                       unsigned long arg)
+{
+       lkdtm_handler();
+       jprobe_return();
+       return 0;
+}
+#endif
+
+static int lkdtm_parse_commandline(void)
+{
+       int i;
+
+       if (cpoint_name == INVALID || cpoint_type == NONE ||
+                                       cpoint_count < 1 || recur_count < 1)
+               return -EINVAL;
+
+       for (i = 0; i < NUM_CPOINTS; ++i) {
+               if (!strcmp(cpoint_name, cp_name[i])) {
+                       cpoint = i + 1;
+                       break;
+               }
+       }
+
+       for (i = 0; i < NUM_CPOINT_TYPES; ++i) {
+               if (!strcmp(cpoint_type, cp_type[i])) {
+                       cptype = i + 1;
+                       break;
+               }
+       }
+
+       if (cpoint == INVALID || cptype == NONE)
+                return -EINVAL;
+
+       count = cpoint_count;
+
+       return 0;
+}
+
+static int recursive_loop(int a)
+{
+       char buf[1024];
+
+       memset(buf,0xFF,1024);
+       recur_count--;
+       if (!recur_count)
+               return 0;
+       else
+               return recursive_loop(a);
+}
+
+void lkdtm_handler(void)
+{
+       printk(KERN_INFO "lkdtm : Crash point %s of type %s hit\n",
+                                        cpoint_name, cpoint_type);
+       --count;
+
+       if (count == 0) {
+               switch (cptype) {
+               case NONE:
+                       break;
+               case PANIC:
+                       printk(KERN_INFO "lkdtm : PANIC\n");
+                       panic("dumptest");
+                       break;
+               case BUG:
+                       printk(KERN_INFO "lkdtm : BUG\n");
+                       BUG();
+                       break;
+               case EXCEPTION:
+                       printk(KERN_INFO "lkdtm : EXCEPTION\n");
+                       *((int *) 0) = 0;
+                       break;
+               case LOOP:
+                       printk(KERN_INFO "lkdtm : LOOP\n");
+                       for (;;);
+                       break;
+               case OVERFLOW:
+                       printk(KERN_INFO "lkdtm : OVERFLOW\n");
+                       (void) recursive_loop(0);
+                       break;
+               default:
+                       break;
+               }
+               count = cpoint_count;
+       }
+}
+
+int lkdtm_module_init(void)
+{
+       int ret;
+
+       if (lkdtm_parse_commandline() == -EINVAL) {
+               printk(KERN_INFO "lkdtm : Invalid command\n");
+               return -EINVAL;
+       }
+
+       switch (cpoint) {
+       case INT_HARDWARE_ENTRY:
+               lkdtm.kp.symbol_name = "__do_IRQ";
+               lkdtm.entry = (kprobe_opcode_t*) jp_do_irq;
+               break;
+       case INT_HW_IRQ_EN:
+               lkdtm.kp.symbol_name = "handle_IRQ_event";
+               lkdtm.entry = (kprobe_opcode_t*) jp_handle_irq_event;
+               break;
+       case INT_TASKLET_ENTRY:
+               lkdtm.kp.symbol_name = "tasklet_action";
+               lkdtm.entry = (kprobe_opcode_t*) jp_tasklet_action;
+               break;
+       case FS_DEVRW:
+               lkdtm.kp.symbol_name = "ll_rw_block";
+               lkdtm.entry = (kprobe_opcode_t*) jp_ll_rw_block;
+               break;
+       case MEM_SWAPOUT:
+               lkdtm.kp.symbol_name = "shrink_page_list";
+               lkdtm.entry = (kprobe_opcode_t*) jp_shrink_page_list;
+               break;
+       case TIMERADD:
+               lkdtm.kp.symbol_name = "hrtimer_start";
+               lkdtm.entry = (kprobe_opcode_t*) jp_hrtimer_start;
+               break;
+       case SCSI_DISPATCH_CMD:
+               lkdtm.kp.symbol_name = "scsi_dispatch_cmd";
+               lkdtm.entry = (kprobe_opcode_t*) jp_scsi_dispatch_cmd;
+               break;
+       case IDE_CORE_CP:
+#ifdef CONFIG_IDE
+               lkdtm.kp.symbol_name = "generic_ide_ioctl";
+               lkdtm.entry = (kprobe_opcode_t*) jp_generic_ide_ioctl;
+#else
+               printk(KERN_INFO "lkdtm : Crash point not available\n");
+#endif
+               break;
+       default:
+               printk(KERN_INFO "lkdtm : Invalid Crash Point\n");
+               break;
+       }
+
+       if ((ret = register_jprobe(&lkdtm)) < 0) {
+                printk(KERN_INFO "lkdtm : Couldn't register jprobe\n");
+                return ret;
+       }
+
+       printk(KERN_INFO "lkdtm : Crash point %s of type %s registered\n",
+                                               cpoint_name, cpoint_type);
+       return 0;
+}
+
+void lkdtm_module_exit(void)
+{
+        unregister_jprobe(&lkdtm);
+        printk(KERN_INFO "lkdtm : Crash point unregistered\n");
+}
+
+module_init(lkdtm_module_init);
+module_exit(lkdtm_module_exit);
+
+MODULE_LICENSE("GPL");
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 642d96bc89198488ec3e136f515f7f6058c98fbf..2cc9024362759f2a4bbb0963c53090b19892ea94 100644 (file)
@@ -96,7 +96,7 @@ static struct mtd_partition arctic_partitions[PARTITIONS] = {
 static int __init
 init_arctic_mtd(void)
 {
-       int err = 0;
+       int err;
 
        printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR);
 
@@ -112,7 +112,7 @@ init_arctic_mtd(void)
        arctic_mtd = do_map_probe("cfi_probe", &arctic_mtd_map);
 
        if (!arctic_mtd) {
-               iounmap((void *) arctic_mtd_map.virt);
+               iounmap(arctic_mtd_map.virt);
                return -ENXIO;
        }
 
@@ -121,7 +121,7 @@ init_arctic_mtd(void)
        err = add_mtd_partitions(arctic_mtd, arctic_partitions, PARTITIONS);
        if (err) {
                printk("%s: add_mtd_partitions failed\n", NAME);
-               iounmap((void *) arctic_mtd_map.virt);
+               iounmap(arctic_mtd_map.virt);
        }
 
        return err;
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 a64b1a5ab3161d57c47f639433280c8f0f51bdb7..d76d5981b8639f965aa15d189874163f28449c29 100644 (file)
@@ -72,7 +72,7 @@ static struct mtd_partition beech_partitions[2] = {
 static int __init
 init_beech_mtd(void)
 {
-       int err = 0;
+       int err;
 
        printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR);
 
@@ -89,7 +89,7 @@ init_beech_mtd(void)
        beech_mtd = do_map_probe("cfi_probe", &beech_mtd_map);
 
        if (!beech_mtd) {
-               iounmap((void *) beech_mtd_map.virt);
+               iounmap(beech_mtd_map.virt);
                return -ENXIO;
        }
 
@@ -98,7 +98,7 @@ init_beech_mtd(void)
        err = add_mtd_partitions(beech_mtd, beech_partitions, 2);
        if (err) {
                printk("%s: add_mtd_partitions failed\n", NAME);
-               iounmap((void *) beech_mtd_map.virt);
+               iounmap(beech_mtd_map.virt);
        }
 
        return err;
index d6bef100d69a2b2f3be47aa71f537bd4c8ed44ee..df2c38ef105ad476769c0d30004f6a3ea61e9549 100644 (file)
@@ -175,8 +175,8 @@ int __init init_cstm_mips_ixx(void)
                        printk(KERN_WARNING "Failed to ioremap\n");
                        for (j = 0; j < i; j++) {
                                if (cstm_mips_ixx_map[j].virt) {
-                                       iounmap((void *)cstm_mips_ixx_map[j].virt);
-                                       cstm_mips_ixx_map[j].virt = 0;
+                                       iounmap(cstm_mips_ixx_map[j].virt);
+                                       cstm_mips_ixx_map[j].virt = NULL;
                                }
                        }
                        return -EIO;
@@ -214,8 +214,8 @@ int __init init_cstm_mips_ixx(void)
                else {
                        for (i = 0; i < PHYSMAP_NUMBER; i++) {
                                if (cstm_mips_ixx_map[i].virt) {
-                                       iounmap((void *)cstm_mips_ixx_map[i].virt);
-                                       cstm_mips_ixx_map[i].virt = 0;
+                                       iounmap(cstm_mips_ixx_map[i].virt);
+                                       cstm_mips_ixx_map[i].virt = NULL;
                                }
                        }
                        return -ENXIO;
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 198e840ff6db9060230b0675f79d698c26bac273..f9e8e5bcbc3354d659520e7e68c4b219c15dfa35 100644 (file)
@@ -463,7 +463,7 @@ int __init nettel_init(void)
 
 #ifdef CONFIG_MTD_CFI_INTELEXT
 out_unmap1:
-       iounmap((void *) nettel_intel_map.virt);
+       iounmap(nettel_intel_map.virt);
 #endif
 
 out_unmap2:
index 2257d2b500c00dd092907951c2a55a36132c2edf..4d858b3d5f826f368872d5317ecc4e9388c91a7c 100644 (file)
@@ -126,7 +126,7 @@ static struct mtd_info *redwood_mtd;
 
 int __init init_redwood_flash(void)
 {
-       int err = 0;
+       int err;
 
        printk(KERN_NOTICE "redwood: flash mapping: %x at %x\n",
                        WINDOW_SIZE, WINDOW_ADDR);
index 6baf5fe142305cfa1131a0be93a838e3e803a9a4..178b53b56be91380cbbf3e1f2d46c01bd60470c1 100644 (file)
@@ -69,7 +69,7 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
                return 1;
 
        default:
-               printk(KERN_NOTICE "Unknown request %ld\n", rq_data_dir(req));
+               printk(KERN_NOTICE "Unknown request %u\n", rq_data_dir(req));
                return 0;
        }
 }
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 12017f3c6bd68ea026f794d85badd1cbf99aa348..1daf8231aaefc079885be293a7f598e88bb87401 100644 (file)
@@ -199,7 +199,7 @@ static void __exit ep7312_cleanup(void)
        nand_release(ap7312_mtd);
 
        /* Release io resource */
-       iounmap((void *)this->IO_ADDR_R);
+       iounmap(this->IO_ADDR_R);
 
        /* Free the MTD device structure */
        kfree(ep7312_mtd);
index 975b2ef611215061de098d5027cd72b63cb47463..baece61169f4933af73704779143ddbaf21c08f7 100644 (file)
@@ -415,7 +415,7 @@ static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip,
  * Wait for the ready pin, after a command
  * The timeout is catched later.
  */
-static void nand_wait_ready(struct mtd_info *mtd)
+void nand_wait_ready(struct mtd_info *mtd)
 {
        struct nand_chip *chip = mtd->priv;
        unsigned long timeo = jiffies + 2;
@@ -429,6 +429,7 @@ static void nand_wait_ready(struct mtd_info *mtd)
        } while (time_before(jiffies, timeo));
        led_trigger_event(nand_led_trigger, LED_OFF);
 }
+EXPORT_SYMBOL_GPL(nand_wait_ready);
 
 /**
  * nand_command - [DEFAULT] Send command to NAND device
@@ -766,8 +767,8 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
        int eccbytes = chip->ecc.bytes;
        int eccsteps = chip->ecc.steps;
        uint8_t *p = buf;
-       uint8_t *ecc_calc = chip->buffers.ecccalc;
-       uint8_t *ecc_code = chip->buffers.ecccode;
+       uint8_t *ecc_calc = chip->buffers->ecccalc;
+       uint8_t *ecc_code = chip->buffers->ecccode;
        int *eccpos = chip->ecc.layout->eccpos;
 
        nand_read_page_raw(mtd, chip, buf);
@@ -808,8 +809,8 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
        int eccbytes = chip->ecc.bytes;
        int eccsteps = chip->ecc.steps;
        uint8_t *p = buf;
-       uint8_t *ecc_calc = chip->buffers.ecccalc;
-       uint8_t *ecc_code = chip->buffers.ecccode;
+       uint8_t *ecc_calc = chip->buffers->ecccalc;
+       uint8_t *ecc_code = chip->buffers->ecccode;
        int *eccpos = chip->ecc.layout->eccpos;
 
        for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
@@ -970,7 +971,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
        page = realpage & chip->pagemask;
 
        col = (int)(from & (mtd->writesize - 1));
-       chip->oob_poi = chip->buffers.oobrbuf;
+       chip->oob_poi = chip->buffers->oobrbuf;
 
        buf = ops->datbuf;
        oob = ops->oobbuf;
@@ -981,7 +982,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
 
                /* Is the current page in the buffer ? */
                if (realpage != chip->pagebuf || oob) {
-                       bufpoi = aligned ? buf : chip->buffers.databuf;
+                       bufpoi = aligned ? buf : chip->buffers->databuf;
 
                        if (likely(sndcmd)) {
                                chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
@@ -989,14 +990,17 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
                        }
 
                        /* Now read the page into the buffer */
-                       ret = chip->ecc.read_page(mtd, chip, bufpoi);
+                       if (unlikely(ops->mode == MTD_OOB_RAW))
+                               ret = chip->ecc.read_page_raw(mtd, chip, bufpoi);
+                       else
+                               ret = chip->ecc.read_page(mtd, chip, bufpoi);
                        if (ret < 0)
                                break;
 
                        /* Transfer not aligned data */
                        if (!aligned) {
                                chip->pagebuf = realpage;
-                               memcpy(buf, chip->buffers.databuf + col, bytes);
+                               memcpy(buf, chip->buffers->databuf + col, bytes);
                        }
 
                        buf += bytes;
@@ -1023,7 +1027,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
                                        nand_wait_ready(mtd);
                        }
                } else {
-                       memcpy(buf, chip->buffers.databuf + col, bytes);
+                       memcpy(buf, chip->buffers->databuf + col, bytes);
                        buf += bytes;
                }
 
@@ -1266,7 +1270,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
        realpage = (int)(from >> chip->page_shift);
        page = realpage & chip->pagemask;
 
-       chip->oob_poi = chip->buffers.oobrbuf;
+       chip->oob_poi = chip->buffers->oobrbuf;
 
        while(1) {
                sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd);
@@ -1322,8 +1326,6 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
 static int nand_read_oob(struct mtd_info *mtd, loff_t from,
                         struct mtd_oob_ops *ops)
 {
-       int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
-                        uint8_t *buf) = NULL;
        struct nand_chip *chip = mtd->priv;
        int ret = -ENOTSUPP;
 
@@ -1341,12 +1343,7 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
        switch(ops->mode) {
        case MTD_OOB_PLACE:
        case MTD_OOB_AUTO:
-               break;
-
        case MTD_OOB_RAW:
-               /* Replace the read_page algorithm temporary */
-               read_page = chip->ecc.read_page;
-               chip->ecc.read_page = nand_read_page_raw;
                break;
 
        default:
@@ -1358,8 +1355,6 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
        else
                ret = nand_do_read_ops(mtd, from, ops);
 
-       if (unlikely(ops->mode == MTD_OOB_RAW))
-               chip->ecc.read_page = read_page;
  out:
        nand_release_device(mtd);
        return ret;
@@ -1391,7 +1386,7 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
        int i, eccsize = chip->ecc.size;
        int eccbytes = chip->ecc.bytes;
        int eccsteps = chip->ecc.steps;
-       uint8_t *ecc_calc = chip->buffers.ecccalc;
+       uint8_t *ecc_calc = chip->buffers->ecccalc;
        const uint8_t *p = buf;
        int *eccpos = chip->ecc.layout->eccpos;
 
@@ -1417,7 +1412,7 @@ static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
        int i, eccsize = chip->ecc.size;
        int eccbytes = chip->ecc.bytes;
        int eccsteps = chip->ecc.steps;
-       uint8_t *ecc_calc = chip->buffers.ecccalc;
+       uint8_t *ecc_calc = chip->buffers->ecccalc;
        const uint8_t *p = buf;
        int *eccpos = chip->ecc.layout->eccpos;
 
@@ -1478,7 +1473,7 @@ static void nand_write_page_syndrome(struct mtd_info *mtd,
 }
 
 /**
- * nand_write_page - [INTERNAL] write one page
+ * nand_write_page - [REPLACEABLE] write one page
  * @mtd:       MTD device structure
  * @chip:      NAND chip descriptor
  * @buf:       the data to write
@@ -1486,13 +1481,16 @@ static void nand_write_page_syndrome(struct mtd_info *mtd,
  * @cached:    cached programming
  */
 static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
-                          const uint8_t *buf, int page, int cached)
+                          const uint8_t *buf, int page, int cached, int raw)
 {
        int status;
 
        chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
 
-       chip->ecc.write_page(mtd, chip, buf);
+       if (unlikely(raw))
+               chip->ecc.write_page_raw(mtd, chip, buf);
+       else
+               chip->ecc.write_page(mtd, chip, buf);
 
        /*
         * Cached progamming disabled for now, Not sure if its worth the
@@ -1627,7 +1625,7 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
            (chip->pagebuf << chip->page_shift) < (to + ops->len))
                chip->pagebuf = -1;
 
-       chip->oob_poi = chip->buffers.oobwbuf;
+       chip->oob_poi = chip->buffers->oobwbuf;
 
        while(1) {
                int cached = writelen > bytes && page != blockmask;
@@ -1635,7 +1633,8 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
                if (unlikely(oob))
                        oob = nand_fill_oob(chip, oob, ops);
 
-               ret = nand_write_page(mtd, chip, buf, page, cached);
+               ret = chip->write_page(mtd, chip, buf, page, cached,
+                                      (ops->mode == MTD_OOB_RAW));
                if (ret)
                        break;
 
@@ -1745,7 +1744,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
        if (page == chip->pagebuf)
                chip->pagebuf = -1;
 
-       chip->oob_poi = chip->buffers.oobwbuf;
+       chip->oob_poi = chip->buffers->oobwbuf;
        memset(chip->oob_poi, 0xff, mtd->oobsize);
        nand_fill_oob(chip, ops->oobbuf, ops);
        status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask);
@@ -1768,8 +1767,6 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
 static int nand_write_oob(struct mtd_info *mtd, loff_t to,
                          struct mtd_oob_ops *ops)
 {
-       void (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
-                         const uint8_t *buf) = NULL;
        struct nand_chip *chip = mtd->priv;
        int ret = -ENOTSUPP;
 
@@ -1787,12 +1784,7 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
        switch(ops->mode) {
        case MTD_OOB_PLACE:
        case MTD_OOB_AUTO:
-               break;
-
        case MTD_OOB_RAW:
-               /* Replace the write_page algorithm temporary */
-               write_page = chip->ecc.write_page;
-               chip->ecc.write_page = nand_write_page_raw;
                break;
 
        default:
@@ -1804,8 +1796,6 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
        else
                ret = nand_do_write_ops(mtd, to, ops);
 
-       if (unlikely(ops->mode == MTD_OOB_RAW))
-               chip->ecc.write_page = write_page;
  out:
        nand_release_device(mtd);
        return ret;
@@ -2288,40 +2278,22 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
        return type;
 }
 
-/* module_text_address() isn't exported, and it's mostly a pointless
-   test if this is a module _anyway_ -- they'd have to try _really_ hard
-   to call us from in-kernel code if the core NAND support is modular. */
-#ifdef MODULE
-#define caller_is_module() (1)
-#else
-#define caller_is_module() \
-       module_text_address((unsigned long)__builtin_return_address(0))
-#endif
-
 /**
- * nand_scan - [NAND Interface] Scan for the NAND device
- * @mtd:       MTD device structure
- * @maxchips:  Number of chips to scan for
+ * nand_scan_ident - [NAND Interface] Scan for the NAND device
+ * @mtd:            MTD device structure
+ * @maxchips:       Number of chips to scan for
  *
- * This fills out all the uninitialized function pointers
- * with the defaults.
- * The flash ID is read and the mtd/chip structures are
- * filled with the appropriate values.
- * The mtd->owner field must be set to the module of the caller
+ * This is the first phase of the normal nand_scan() function. It
+ * reads the flash ID and sets up MTD fields accordingly.
  *
+ * The mtd->owner field must be set to the module of the caller.
  */
-int nand_scan(struct mtd_info *mtd, int maxchips)
+int nand_scan_ident(struct mtd_info *mtd, int maxchips)
 {
        int i, busw, nand_maf_id;
        struct nand_chip *chip = mtd->priv;
        struct nand_flash_dev *type;
 
-       /* Many callers got this wrong, so check for it for a while... */
-       if (!mtd->owner && caller_is_module()) {
-               printk(KERN_CRIT "nand_scan() called with NULL mtd->owner!\n");
-               BUG();
-       }
-
        /* Get buswidth to select the correct functions */
        busw = chip->options & NAND_BUSWIDTH_16;
        /* Set the default functions */
@@ -2353,8 +2325,31 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
        chip->numchips = i;
        mtd->size = i * chip->chipsize;
 
+       return 0;
+}
+
+
+/**
+ * nand_scan_tail - [NAND Interface] Scan for the NAND device
+ * @mtd:           MTD device structure
+ * @maxchips:      Number of chips to scan for
+ *
+ * This is the second phase of the normal nand_scan() function. It
+ * fills out all the uninitialized function pointers with the defaults
+ * and scans for a bad block table if appropriate.
+ */
+int nand_scan_tail(struct mtd_info *mtd)
+{
+       int i;
+       struct nand_chip *chip = mtd->priv;
+
+       if (!(chip->options & NAND_OWN_BUFFERS))
+               chip->buffers = kmalloc(sizeof(*chip->buffers), GFP_KERNEL);
+       if (!chip->buffers)
+               return -ENOMEM;
+
        /* Preset the internal oob write buffer */
-       memset(chip->buffers.oobwbuf, 0xff, mtd->oobsize);
+       memset(chip->buffers->oobwbuf, 0xff, mtd->oobsize);
 
        /*
         * If no default placement scheme is given, select an appropriate one
@@ -2377,10 +2372,18 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
                }
        }
 
+       if (!chip->write_page)
+               chip->write_page = nand_write_page;
+
        /*
         * check ECC mode, default to software if 3byte/512byte hardware ECC is
         * selected and we have 256 byte pagesize fallback to software ECC
         */
+       if (!chip->ecc.read_page_raw)
+               chip->ecc.read_page_raw = nand_read_page_raw;
+       if (!chip->ecc.write_page_raw)
+               chip->ecc.write_page_raw = nand_write_page_raw;
+
        switch (chip->ecc.mode) {
        case NAND_ECC_HW:
                /* Use standard hwecc read page function ? */
@@ -2438,6 +2441,7 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
                chip->ecc.size = mtd->writesize;
                chip->ecc.bytes = 0;
                break;
+
        default:
                printk(KERN_WARNING "Invalid NAND_ECC_MODE %d\n",
                       chip->ecc.mode);
@@ -2503,6 +2507,44 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
        return chip->scan_bbt(mtd);
 }
 
+/* module_text_address() isn't exported, and it's mostly a pointless
+   test if this is a module _anyway_ -- they'd have to try _really_ hard
+   to call us from in-kernel code if the core NAND support is modular. */
+#ifdef MODULE
+#define caller_is_module() (1)
+#else
+#define caller_is_module() \
+       module_text_address((unsigned long)__builtin_return_address(0))
+#endif
+
+/**
+ * nand_scan - [NAND Interface] Scan for the NAND device
+ * @mtd:       MTD device structure
+ * @maxchips:  Number of chips to scan for
+ *
+ * This fills out all the uninitialized function pointers
+ * with the defaults.
+ * The flash ID is read and the mtd/chip structures are
+ * filled with the appropriate values.
+ * The mtd->owner field must be set to the module of the caller
+ *
+ */
+int nand_scan(struct mtd_info *mtd, int maxchips)
+{
+       int ret;
+
+       /* Many callers got this wrong, so check for it for a while... */
+       if (!mtd->owner && caller_is_module()) {
+               printk(KERN_CRIT "nand_scan() called with NULL mtd->owner!\n");
+               BUG();
+       }
+
+       ret = nand_scan_ident(mtd, maxchips);
+       if (!ret)
+               ret = nand_scan_tail(mtd);
+       return ret;
+}
+
 /**
  * nand_release - [NAND Interface] Free resources held by the NAND device
  * @mtd:       MTD device structure
@@ -2520,9 +2562,13 @@ void nand_release(struct mtd_info *mtd)
 
        /* Free bad block table memory */
        kfree(chip->bbt);
+       if (!(chip->options & NAND_OWN_BUFFERS))
+               kfree(chip->buffers);
 }
 
 EXPORT_SYMBOL_GPL(nand_scan);
+EXPORT_SYMBOL_GPL(nand_scan_ident);
+EXPORT_SYMBOL_GPL(nand_scan_tail);
 EXPORT_SYMBOL_GPL(nand_release);
 
 static int __init nand_base_init(void)
index a612c4ea8194d86750c39d0aac18784cbfe20606..9402653eb09b4982ac7d924beda88cb203442741 100644 (file)
@@ -759,7 +759,7 @@ static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *b
        struct nand_chip *this = mtd->priv;
 
        bd->options &= ~NAND_BBT_SCANEMPTY;
-       return create_bbt(mtd, this->buffers.databuf, bd, -1);
+       return create_bbt(mtd, this->buffers->databuf, bd, -1);
 }
 
 /**
index dd5cea8b4a7a2dc31b1429ce6a7ebe07c143ec7b..b5a5f8da4722e78ecd8d00efc50cca97724c34f3 100644 (file)
@@ -175,6 +175,8 @@ int nftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
        return res;
 }
 
+#ifdef CONFIG_NFTL_RW
+
 /*
  * Write data and oob to flash
  */
@@ -196,8 +198,6 @@ static int nftl_write(struct mtd_info *mtd, loff_t offs, size_t len,
        return res;
 }
 
-#ifdef CONFIG_NFTL_RW
-
 /* Actual NFTL access routines */
 /* NFTL_findfreeblock: Find a free Erase Unit on the NFTL partition. This function is used
  *     when the give Virtual Unit Chain
index 5930a03736d7557ab9bdfc9137bb604a863560d1..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"
@@ -43,10 +43,4 @@ config MTD_ONENAND_OTP
 
          OTP block is fully-guaranteed to be a valid block.
 
-config MTD_ONENAND_SYNC_READ
-       bool "OneNAND Sync. Burst Read Support"
-       depends on ARCH_OMAP
-       help
-         This enables support for Sync. Burst Read.
-
 endmenu
index 84ec40d254386f366a3d4e2f92ad54cda2663eb9..8ed68b28afe37651d85500889676f7a48a93e9b0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  linux/drivers/mtd/onenand/onenand_base.c
  *
- *  Copyright (C) 2005 Samsung Electronics
+ *  Copyright (C) 2005-2006 Samsung Electronics
  *  Kyungmin Park <kyungmin.park@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -199,6 +199,7 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
        case ONENAND_CMD_UNLOCK:
        case ONENAND_CMD_LOCK:
        case ONENAND_CMD_LOCK_TIGHT:
+       case ONENAND_CMD_UNLOCK_ALL:
                block = -1;
                page = -1;
                break;
@@ -1211,11 +1212,11 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
        end = len >> this->erase_shift;
 
        /* Continuous lock scheme */
-       if (this->options & ONENAND_CONT_LOCK) {
+       if (this->options & ONENAND_HAS_CONT_LOCK) {
                /* Set start block address */
                this->write_word(start, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
                /* Set end block address */
-               this->write_word(end - 1, this->base + ONENAND_REG_END_BLOCK_ADDRESS);
+               this->write_word(start + end - 1, this->base + ONENAND_REG_END_BLOCK_ADDRESS);
                /* Write unlock command */
                this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
 
@@ -1236,7 +1237,7 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
        }
 
        /* Block lock scheme */
-       for (block = start; block < end; block++) {
+       for (block = start; block < start + end; block++) {
                /* Set block address */
                value = onenand_block_address(this, block);
                this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
@@ -1265,6 +1266,79 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
        return 0;
 }
 
+/**
+ * onenand_check_lock_status - [OneNAND Interface] Check lock status
+ * @param this         onenand chip data structure
+ *
+ * Check lock status
+ */
+static void onenand_check_lock_status(struct onenand_chip *this)
+{
+       unsigned int value, block, status;
+       unsigned int end;
+
+       end = this->chipsize >> this->erase_shift;
+       for (block = 0; block < end; block++) {
+               /* Set block address */
+               value = onenand_block_address(this, block);
+               this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
+               /* Select DataRAM for DDP */
+               value = onenand_bufferram_address(this, block);
+               this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
+               /* Set start block address */
+               this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
+
+               /* Check lock status */
+               status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
+               if (!(status & ONENAND_WP_US))
+                       printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status);
+       }
+}
+
+/**
+ * onenand_unlock_all - [OneNAND Interface] unlock all blocks
+ * @param mtd          MTD device structure
+ *
+ * Unlock all blocks
+ */
+static int onenand_unlock_all(struct mtd_info *mtd)
+{
+       struct onenand_chip *this = mtd->priv;
+
+       if (this->options & ONENAND_HAS_UNLOCK_ALL) {
+               /* Write unlock command */
+               this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);
+
+               /* There's no return value */
+               this->wait(mtd, FL_UNLOCKING);
+
+               /* Sanity check */
+               while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
+                   & ONENAND_CTRL_ONGO)
+                       continue;
+
+               /* Workaround for all block unlock in DDP */
+               if (this->device_id & ONENAND_DEVICE_IS_DDP) {
+                       loff_t ofs;
+                       size_t len;
+
+                       /* 1st block on another chip */
+                       ofs = this->chipsize >> 1;
+                       len = 1 << this->erase_shift;
+
+                       onenand_unlock(mtd, ofs, len);
+               }
+
+               onenand_check_lock_status(this);
+
+               return 0;
+       }
+
+       mtd->unlock(mtd, 0x0, this->chipsize);
+
+       return 0;
+}
+
 #ifdef CONFIG_MTD_ONENAND_OTP
 
 /* Interal OTP operation */
@@ -1563,13 +1637,44 @@ static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
 }
 #endif /* CONFIG_MTD_ONENAND_OTP */
 
+/**
+ * onenand_lock_scheme - Check and set OneNAND lock scheme
+ * @param mtd          MTD data structure
+ *
+ * Check and set OneNAND lock scheme
+ */
+static void onenand_lock_scheme(struct mtd_info *mtd)
+{
+       struct onenand_chip *this = mtd->priv;
+       unsigned int density, process;
+
+       /* Lock scheme depends on density and process */
+       density = this->device_id >> ONENAND_DEVICE_DENSITY_SHIFT;
+       process = this->version_id >> ONENAND_VERSION_PROCESS_SHIFT;
+
+       /* Lock scheme */
+       if (density >= ONENAND_DEVICE_DENSITY_1Gb) {
+               /* A-Die has all block unlock */
+               if (process) {
+                       printk(KERN_DEBUG "Chip support all block unlock\n");
+                       this->options |= ONENAND_HAS_UNLOCK_ALL;
+               }
+       } else {
+               /* Some OneNAND has continues lock scheme */
+               if (!process) {
+                       printk(KERN_DEBUG "Lock scheme is Continues Lock\n");
+                       this->options |= ONENAND_HAS_CONT_LOCK;
+               }
+       }
+}
+
 /**
  * onenand_print_device_info - Print device ID
  * @param device        device ID
  *
  * Print device ID
  */
-static void onenand_print_device_info(int device)
+static void onenand_print_device_info(int device, int version)
 {
         int vcc, demuxed, ddp, density;
 
@@ -1583,6 +1688,7 @@ static void onenand_print_device_info(int device)
                 (16 << density),
                 vcc ? "2.65/3.3" : "1.8",
                 device);
+       printk(KERN_DEBUG "OneNAND version = 0x%04x\n", version);
 }
 
 static const struct onenand_manufacturers onenand_manuf_ids[] = {
@@ -1625,9 +1731,14 @@ static int onenand_check_maf(int manuf)
 static int onenand_probe(struct mtd_info *mtd)
 {
        struct onenand_chip *this = mtd->priv;
-       int bram_maf_id, bram_dev_id, maf_id, dev_id;
-       int version_id;
+       int bram_maf_id, bram_dev_id, maf_id, dev_id, ver_id;
        int density;
+       int syscfg;
+
+       /* Save system configuration 1 */
+       syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
+       /* Clear Sync. Burst Read mode to read BootRAM */
+       this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ), this->base + ONENAND_REG_SYS_CFG1);
 
        /* Send the command for reading device ID from BootRAM */
        this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
@@ -1636,24 +1747,31 @@ static int onenand_probe(struct mtd_info *mtd)
        bram_maf_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x0);
        bram_dev_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x2);
 
+       /* Reset OneNAND to read default register values */
+       this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
+       /* Wait reset */
+       this->wait(mtd, FL_RESETING);
+
+       /* Restore system configuration 1 */
+       this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
+
        /* Check manufacturer ID */
        if (onenand_check_maf(bram_maf_id))
                return -ENXIO;
 
-       /* Reset OneNAND to read default register values */
-       this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
-
        /* Read manufacturer and device IDs from Register */
        maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
        dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
+       ver_id= this->read_word(this->base + ONENAND_REG_VERSION_ID);
 
        /* Check OneNAND device */
        if (maf_id != bram_maf_id || dev_id != bram_dev_id)
                return -ENXIO;
 
        /* Flash device information */
-       onenand_print_device_info(dev_id);
+       onenand_print_device_info(dev_id, ver_id);
        this->device_id = dev_id;
+       this->version_id = ver_id;
 
        density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
        this->chipsize = (16 << density) << 20;
@@ -1676,16 +1794,8 @@ static int onenand_probe(struct mtd_info *mtd)
 
        mtd->size = this->chipsize;
 
-       /* Version ID */
-       version_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
-       printk(KERN_DEBUG "OneNAND version = 0x%04x\n", version_id);
-
-       /* Lock scheme */
-       if (density <= ONENAND_DEVICE_DENSITY_512Mb &&
-           !(version_id >> ONENAND_VERSION_PROCESS_SHIFT)) {
-               printk(KERN_INFO "Lock scheme is Continues Lock\n");
-               this->options |= ONENAND_CONT_LOCK;
-       }
+       /* Check OneNAND lock scheme */
+       onenand_lock_scheme(mtd);
 
        return 0;
 }
@@ -1821,7 +1931,7 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
        mtd->owner = THIS_MODULE;
 
        /* Unlock whole block */
-       mtd->unlock(mtd, 0x0, this->chipsize);
+       onenand_unlock_all(mtd);
 
        return this->scan_bbt(mtd);
 }
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 9953201c670dcaab69b88a8bad8a3b5e19b8a729..a67f5efc983f29be5ec116bf09bd6113277f3534 100644 (file)
@@ -165,7 +165,7 @@ static struct devprobe2 mca_probes[] __initdata = {
  * look for EISA/PCI/MCA cards in addition to ISA cards).
  */
 static struct devprobe2 isa_probes[] __initdata = {
-#ifdef CONFIG_HP100            /* ISA, EISA & PCI */
+#if defined(CONFIG_HP100) && defined(CONFIG_ISA)       /* ISA, EISA */
        {hp100_probe, 0},
 #endif
 #ifdef CONFIG_3C515
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 dc5e38aefca6adc706ae9feb27ea2d9d87162d93..26073c3452130b01aaaa3ce83d20b10f2919c382 100644 (file)
@@ -1,27 +1,27 @@
 /*******************************************************************************
 
-
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
+  Intel PRO/100 Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by the Free
-  Software Foundation; either version 2 of the License, or (at your option)
-  any later version.
+  under the terms and conditions 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
+  This program is distributed in the hope it will be useful, but WITHOUT
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.
 
   You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
 
   Contact Information:
   Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 *******************************************************************************/
 
 #define DRV_NAME               "e100"
 #define DRV_EXT                        "-NAPI"
-#define DRV_VERSION            "3.5.16-k2"DRV_EXT
+#define DRV_VERSION            "3.5.17-k2"DRV_EXT
 #define DRV_DESCRIPTION                "Intel(R) PRO/100 Network Driver"
 #define DRV_COPYRIGHT          "Copyright(c) 1999-2006 Intel Corporation"
 #define PFX                    DRV_NAME ": "
@@ -1657,13 +1657,14 @@ static int e100_tx_clean(struct nic *nic)
 
        spin_lock(&nic->cb_lock);
 
-       DPRINTK(TX_DONE, DEBUG, "cb->status = 0x%04X\n",
-               nic->cb_to_clean->status);
-
        /* Clean CBs marked complete */
        for(cb = nic->cb_to_clean;
            cb->status & cpu_to_le16(cb_complete);
            cb = nic->cb_to_clean = cb->next) {
+               DPRINTK(TX_DONE, DEBUG, "cb[%d]->status = 0x%04X\n",
+                       (int)(((void*)cb - (void*)nic->cbs)/sizeof(struct cb)),
+                       cb->status);
+
                if(likely(cb->skb != NULL)) {
                        nic->net_stats.tx_packets++;
                        nic->net_stats.tx_bytes += cb->skb->len;
@@ -2572,7 +2573,7 @@ static int __devinit e100_probe(struct pci_dev *pdev,
 #ifdef CONFIG_NET_POLL_CONTROLLER
        netdev->poll_controller = e100_netpoll;
 #endif
-       strcpy(netdev->name, pci_name(pdev));
+       strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
 
        nic = netdev_priv(netdev);
        nic->netdev = netdev;
@@ -2714,68 +2715,56 @@ static void __devexit e100_remove(struct pci_dev *pdev)
        }
 }
 
-#ifdef CONFIG_PM
 static int e100_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct nic *nic = netdev_priv(netdev);
-       int retval;
 
-       if(netif_running(netdev))
+       if (netif_running(netdev))
                e100_down(nic);
        e100_hw_reset(nic);
        netif_device_detach(netdev);
 
+#ifdef CONFIG_PM
        pci_save_state(pdev);
-       retval = pci_enable_wake(pdev, pci_choose_state(pdev, state),
-                                nic->flags & (wol_magic | e100_asf(nic)));
-       if (retval)
-               DPRINTK(PROBE,ERR, "Error enabling wake\n");
+       if (nic->flags & (wol_magic | e100_asf(nic)))
+#else
+       if (nic->flags & (wol_magic))
+#endif
+               pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
+       else
+               /* disable PME */
+               pci_enable_wake(pdev, 0, 0);
+
        pci_disable_device(pdev);
-       retval = pci_set_power_state(pdev, pci_choose_state(pdev, state));
-       if (retval)
-               DPRINTK(PROBE,ERR, "Error %d setting power state\n", retval);
+       pci_set_power_state(pdev, pci_choose_state(pdev, state));
 
        return 0;
 }
 
+#ifdef CONFIG_PM
 static int e100_resume(struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct nic *nic = netdev_priv(netdev);
-       int retval;
 
-       retval = pci_set_power_state(pdev, PCI_D0);
-       if (retval)
-               DPRINTK(PROBE,ERR, "Error waking adapter\n");
+       pci_set_power_state(pdev, PCI_D0);
        pci_restore_state(pdev);
        /* ack any pending wake events, disable PME */
-       retval = pci_enable_wake(pdev, 0, 0);
-       if (retval)
-               DPRINTK(PROBE,ERR, "Error clearing wake events\n");
+       pci_enable_wake(pdev, 0, 0);
 
        netif_device_attach(netdev);
-       if(netif_running(netdev))
+       if (netif_running(netdev))
                e100_up(nic);
 
        return 0;
 }
-#endif
+#endif /* CONFIG_PM */
 
 
 static void e100_shutdown(struct pci_dev *pdev)
 {
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct nic *nic = netdev_priv(netdev);
-       int retval;
-
-#ifdef CONFIG_PM
-       retval = pci_enable_wake(pdev, 0, nic->flags & (wol_magic | e100_asf(nic)));
-#else
-       retval = pci_enable_wake(pdev, 0, nic->flags & (wol_magic));
-#endif
-       if (retval)
-               DPRINTK(PROBE,ERR, "Error enabling wake\n");
+       e100_suspend(pdev, PMSG_SUSPEND);
 }
 
 /* ------------------ PCI Error Recovery infrastructure  -------------- */
@@ -2859,8 +2848,9 @@ static struct pci_driver e100_driver = {
        .id_table =     e100_id_table,
        .probe =        e100_probe,
        .remove =       __devexit_p(e100_remove),
-#ifdef CONFIG_PM
+       /* Power Management hooks */
        .suspend =      e100_suspend,
+#ifdef CONFIG_PM
        .resume =       e100_resume,
 #endif
        .shutdown =     e100_shutdown,
diff --git a/drivers/net/e1000/LICENSE b/drivers/net/e1000/LICENSE
deleted file mode 100644 (file)
index 5f297e5..0000000
+++ /dev/null
@@ -1,339 +0,0 @@
-
-"This software program is licensed subject to the GNU General Public License 
-(GPL). Version 2, June 1991, available at 
-<http://www.fsf.org/copyleft/gpl.html>"
-
-GNU General Public License 
-
-Version 2, June 1991
-
-Copyright (C) 1989, 1991 Free Software Foundation, Inc.  
-59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
-
-Everyone is permitted to copy and distribute verbatim copies of this license
-document, but changing it is not allowed.
-
-Preamble
-
-The licenses for most software are designed to take away your freedom to 
-share and change it. By contrast, the GNU General Public License is intended
-to guarantee your freedom to share and change free software--to make sure 
-the software is free for all its users. This General Public License applies 
-to most of the Free Software Foundation's software and to any other program 
-whose authors commit to using it. (Some other Free Software Foundation 
-software is covered by the GNU Library General Public License instead.) You 
-can apply it to your programs, too.
-
-When we speak of free software, we are referring to freedom, not price. Our
-General Public Licenses are designed to make sure that you have the freedom 
-to distribute copies of free software (and charge for this service if you 
-wish), that you receive source code or can get it if you want it, that you 
-can change the software or use pieces of it in new free programs; and that 
-you know you can do these things.
-
-To protect your rights, we need to make restrictions that forbid anyone to 
-deny you these rights or to ask you to surrender the rights. These 
-restrictions translate to certain responsibilities for you if you distribute
-copies of the software, or if you modify it.
-
-For example, if you distribute copies of such a program, whether gratis or 
-for a fee, you must give the recipients all the rights that you have. You 
-must make sure that they, too, receive or can get the source code. And you 
-must show them these terms so they know their rights.
-We protect your rights with two steps: (1) copyright the software, and (2) 
-offer you this license which gives you legal permission to copy, distribute 
-and/or modify the software. 
-
-Also, for each author's protection and ours, we want to make certain that 
-everyone understands that there is no warranty for this free software. If 
-the software is modified by someone else and passed on, we want its 
-recipients to know that what they have is not the original, so that any 
-problems introduced by others will not reflect on the original authors' 
-reputations. 
-
-Finally, any free program is threatened constantly by software patents. We 
-wish to avoid the danger that redistributors of a free program will 
-individually obtain patent licenses, in effect making the program 
-proprietary. To prevent this, we have made it clear that any patent must be 
-licensed for everyone's free use or not licensed at all. 
-
-The precise terms and conditions for copying, distribution and modification 
-follow. 
-
-TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-0. This License applies to any program or other work which contains a notice
-   placed by the copyright holder saying it may be distributed under the 
-   terms of this General Public License. The "Program", below, refers to any
-   such program or work, and a "work based on the Program" means either the 
-   Program or any derivative work under copyright law: that is to say, a 
-   work containing the Program or a portion of it, either verbatim or with 
-   modifications and/or translated into another language. (Hereinafter, 
-   translation is included without limitation in the term "modification".) 
-   Each licensee is addressed as "you". 
-
-   Activities other than copying, distribution and modification are not 
-   covered by this License; they are outside its scope. The act of running 
-   the Program is not restricted, and the output from the Program is covered 
-   only if its contents constitute a work based on the Program (independent 
-   of having been made by running the Program). Whether that is true depends
-   on what the Program does. 
-
-1. You may copy and distribute verbatim copies of the Program's source code 
-   as you receive it, in any medium, provided that you conspicuously and 
-   appropriately publish on each copy an appropriate copyright notice and 
-   disclaimer of warranty; keep intact all the notices that refer to this 
-   License and to the absence of any warranty; and give any other recipients 
-   of the Program a copy of this License along with the Program. 
-
-   You may charge a fee for the physical act of transferring a copy, and you 
-   may at your option offer warranty protection in exchange for a fee. 
-
-2. You may modify your copy or copies of the Program or any portion of it, 
-   thus forming a work based on the Program, and copy and distribute such 
-   modifications or work under the terms of Section 1 above, provided that 
-   you also meet all of these conditions: 
-
-   * a) You must cause the modified files to carry prominent notices stating 
-        that you changed the files and the date of any change. 
-
-   * b) You must cause any work that you distribute or publish, that in 
-        whole or in part contains or is derived from the Program or any part 
-        thereof, to be licensed as a whole at no charge to all third parties
-        under the terms of this License. 
-
-   * c) If the modified program normally reads commands interactively when 
-        run, you must cause it, when started running for such interactive 
-        use in the most ordinary way, to print or display an announcement 
-        including an appropriate copyright notice and a notice that there is
-        no warranty (or else, saying that you provide a warranty) and that 
-        users may redistribute the program under these conditions, and 
-        telling the user how to view a copy of this License. (Exception: if 
-        the Program itself is interactive but does not normally print such 
-        an announcement, your work based on the Program is not required to 
-        print an announcement.) 
-
-   These requirements apply to the modified work as a whole. If identifiable 
-   sections of that work are not derived from the Program, and can be 
-   reasonably considered independent and separate works in themselves, then 
-   this License, and its terms, do not apply to those sections when you 
-   distribute them as separate works. But when you distribute the same 
-   sections as part of a whole which is a work based on the Program, the 
-   distribution of the whole must be on the terms of this License, whose 
-   permissions for other licensees extend to the entire whole, and thus to 
-   each and every part regardless of who wrote it. 
-
-   Thus, it is not the intent of this section to claim rights or contest 
-   your rights to work written entirely by you; rather, the intent is to 
-   exercise the right to control the distribution of derivative or 
-   collective works based on the Program. 
-
-   In addition, mere aggregation of another work not based on the Program 
-   with the Program (or with a work based on the Program) on a volume of a 
-   storage or distribution medium does not bring the other work under the 
-   scope of this License. 
-
-3. You may copy and distribute the Program (or a work based on it, under 
-   Section 2) in object code or executable form under the terms of Sections 
-   1 and 2 above provided that you also do one of the following: 
-
-   * a) Accompany it with the complete corresponding machine-readable source 
-        code, which must be distributed under the terms of Sections 1 and 2 
-        above on a medium customarily used for software interchange; or, 
-
-   * b) Accompany it with a written offer, valid for at least three years, 
-        to give any third party, for a charge no more than your cost of 
-        physically performing source distribution, a complete machine-
-        readable copy of the corresponding source code, to be distributed 
-        under the terms of Sections 1 and 2 above on a medium customarily 
-        used for software interchange; or, 
-
-   * c) Accompany it with the information you received as to the offer to 
-        distribute corresponding source code. (This alternative is allowed 
-        only for noncommercial distribution and only if you received the 
-        program in object code or executable form with such an offer, in 
-        accord with Subsection b above.) 
-
-   The source code for a work means the preferred form of the work for 
-   making modifications to it. For an executable work, complete source code 
-   means all the source code for all modules it contains, plus any 
-   associated interface definition files, plus the scripts used to control 
-   compilation and installation of the executable. However, as a special 
-   exception, the source code distributed need not include anything that is 
-   normally distributed (in either source or binary form) with the major 
-   components (compiler, kernel, and so on) of the operating system on which
-   the executable runs, unless that component itself accompanies the 
-   executable. 
-
-   If distribution of executable or object code is made by offering access 
-   to copy from a designated place, then offering equivalent access to copy 
-   the source code from the same place counts as distribution of the source 
-   code, even though third parties are not compelled to copy the source 
-   along with the object code. 
-
-4. You may not copy, modify, sublicense, or distribute the Program except as
-   expressly provided under this License. Any attempt otherwise to copy, 
-   modify, sublicense or distribute the Program is void, and will 
-   automatically terminate your rights under this License. However, parties 
-   who have received copies, or rights, from you under this License will not
-   have their licenses terminated so long as such parties remain in full 
-   compliance. 
-
-5. You are not required to accept this License, since you have not signed 
-   it. However, nothing else grants you permission to modify or distribute 
-   the Program or its derivative works. These actions are prohibited by law 
-   if you do not accept this License. Therefore, by modifying or 
-   distributing the Program (or any work based on the Program), you 
-   indicate your acceptance of this License to do so, and all its terms and
-   conditions for copying, distributing or modifying the Program or works 
-   based on it. 
-
-6. Each time you redistribute the Program (or any work based on the 
-   Program), the recipient automatically receives a license from the 
-   original licensor to copy, distribute or modify the Program subject to 
-   these terms and conditions. You may not impose any further restrictions 
-   on the recipients' exercise of the rights granted herein. You are not 
-   responsible for enforcing compliance by third parties to this License. 
-
-7. If, as a consequence of a court judgment or allegation of patent 
-   infringement or for any other reason (not limited to patent issues), 
-   conditions are imposed on you (whether by court order, agreement or 
-   otherwise) that contradict the conditions of this License, they do not 
-   excuse you from the conditions of this License. If you cannot distribute 
-   so as to satisfy simultaneously your obligations under this License and 
-   any other pertinent obligations, then as a consequence you may not 
-   distribute the Program at all. For example, if a patent license would 
-   not permit royalty-free redistribution of the Program by all those who 
-   receive copies directly or indirectly through you, then the only way you 
-   could satisfy both it and this License would be to refrain entirely from 
-   distribution of the Program. 
-
-   If any portion of this section is held invalid or unenforceable under any
-   particular circumstance, the balance of the section is intended to apply
-   and the section as a whole is intended to apply in other circumstances. 
-
-   It is not the purpose of this section to induce you to infringe any 
-   patents or other property right claims or to contest validity of any 
-   such claims; this section has the sole purpose of protecting the 
-   integrity of the free software distribution system, which is implemented 
-   by public license practices. Many people have made generous contributions
-   to the wide range of software distributed through that system in 
-   reliance on consistent application of that system; it is up to the 
-   author/donor to decide if he or she is willing to distribute software 
-   through any other system and a licensee cannot impose that choice. 
-
-   This section is intended to make thoroughly clear what is believed to be 
-   a consequence of the rest of this License. 
-
-8. If the distribution and/or use of the Program is restricted in certain 
-   countries either by patents or by copyrighted interfaces, the original 
-   copyright holder who places the Program under this License may add an 
-   explicit geographical distribution limitation excluding those countries, 
-   so that distribution is permitted only in or among countries not thus 
-   excluded. In such case, this License incorporates the limitation as if 
-   written in the body of this License. 
-
-9. The Free Software Foundation may publish revised and/or new versions of 
-   the General Public License from time to time. Such new versions will be 
-   similar in spirit to the present version, but may differ in detail to 
-   address new problems or concerns. 
-
-   Each version is given a distinguishing version number. If the Program 
-   specifies a version number of this License which applies to it and "any 
-   later version", you have the option of following the terms and 
-   conditions either of that version or of any later version published by 
-   the Free Software Foundation. If the Program does not specify a version 
-   number of this License, you may choose any version ever published by the 
-   Free Software Foundation. 
-
-10. If you wish to incorporate parts of the Program into other free programs
-    whose distribution conditions are different, write to the author to ask 
-    for permission. For software which is copyrighted by the Free Software 
-    Foundation, write to the Free Software Foundation; we sometimes make 
-    exceptions for this. Our decision will be guided by the two goals of 
-    preserving the free status of all derivatives of our free software and 
-    of promoting the sharing and reuse of software generally. 
-
-   NO WARRANTY
-
-11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 
-    FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 
-    OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 
-    PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER 
-    EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
-    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE 
-    ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH 
-    YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL 
-    NECESSARY SERVICING, REPAIR OR CORRECTION. 
-
-12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 
-    WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 
-    REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR 
-    DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL 
-    DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM 
-    (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED 
-    INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF 
-    THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR 
-    OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 
-
-END OF TERMS AND CONDITIONS
-
-How to Apply These Terms to Your New Programs
-
-If you develop a new program, and you want it to be of the greatest 
-possible use to the public, the best way to achieve this is to make it free 
-software which everyone can redistribute and change under these terms. 
-
-To do so, attach the following notices to the program. It is safest to 
-attach them to the start of each source file to most effectively convey the
-exclusion of warranty; and each file should have at least the "copyright" 
-line and a pointer to where the full notice is found. 
-
-one line to give the program's name and an idea of what it does.
-Copyright (C) yyyy  name of author
-
-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.
-
-Also add information on how to contact you by electronic and paper mail. 
-
-If the program is interactive, make it output a short notice like this when 
-it starts in an interactive mode: 
-
-Gnomovision version 69, Copyright (C) year name of author Gnomovision comes 
-with ABSOLUTELY NO WARRANTY; for details type 'show w'.  This is free 
-software, and you are welcome to redistribute it under certain conditions; 
-type 'show c' for details.
-
-The hypothetical commands 'show w' and 'show c' should show the appropriate 
-parts of the General Public License. Of course, the commands you use may be 
-called something other than 'show w' and 'show c'; they could even be 
-mouse-clicks or menu items--whatever suits your program. 
-
-You should also get your employer (if you work as a programmer) or your 
-school, if any, to sign a "copyright disclaimer" for the program, if 
-necessary. Here is a sample; alter the names: 
-
-Yoyodyne, Inc., hereby disclaims all copyright interest in the program 
-'Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-signature of Ty Coon, 1 April 1989
-Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into 
-proprietary programs. If your program is a subroutine library, you may 
-consider it more useful to permit linking proprietary applications with the 
-library. If this is what you want to do, use the GNU Library General Public 
-License instead of this License.
index 5dea2b7dea4d6b9118f4ad9426ea7093058779e7..4a6ab1522451ca77dbd83b2186125cee0c86a803 100644 (file)
@@ -1,25 +1,24 @@
 ################################################################################
 #
-# 
-# Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-# 
-# This program is free software; you can redistribute it and/or modify it 
-# under the terms of the GNU General Public License as published by the Free 
-# Software Foundation; either version 2 of the License, or (at your option) 
-# any later version.
-# 
-# This program is distributed in the hope that it will be useful, but WITHOUT 
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+# Intel PRO/1000 Linux driver
+# Copyright(c) 1999 - 2006 Intel Corporation.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 # more details.
-# 
+#
 # You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 59 
-# Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-# 
-# The full GNU General Public License is included in this distribution in the
-# file called LICENSE.
-# 
+# this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# The full GNU General Public License is included in this distribution in
+# the file called "COPYING".
+#
 # Contact Information:
 # Linux NICS <linux.nics@intel.com>
 # e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
index 98afa9c2057e7a163f961b32cc346dfff0dbbbe1..7ecce438d2586ba483f16ef19dc2837ba3590487 100644 (file)
@@ -1,25 +1,24 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  any later version.
-  
-  This program is distributed in the hope that it will be useful, but WITHOUT 
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+  Intel PRO/1000 Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.
-  
+
   You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59 
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
@@ -346,29 +345,9 @@ struct e1000_adapter {
 };
 
 enum e1000_state_t {
-       __E1000_DRIVER_TESTING,
+       __E1000_TESTING,
        __E1000_RESETTING,
+       __E1000_DOWN
 };
 
-/*  e1000_main.c  */
-extern char e1000_driver_name[];
-extern char e1000_driver_version[];
-int e1000_up(struct e1000_adapter *adapter);
-void e1000_down(struct e1000_adapter *adapter);
-void e1000_reset(struct e1000_adapter *adapter);
-void e1000_reinit_locked(struct e1000_adapter *adapter);
-int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
-void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
-int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
-void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
-void e1000_update_stats(struct e1000_adapter *adapter);
-int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
-
-/*  e1000_ethtool.c  */
-void e1000_set_ethtool_ops(struct net_device *netdev);
-
-/*  e1000_param.c  */
-void e1000_check_options(struct e1000_adapter *adapter);
-
-
 #endif /* _E1000_H_ */
index e39aa1fc4d1e2592fcbcc69bbe8ee12dbb7d01a1..778ede3c02163a1c4655c092e52196bb903316e3 100644 (file)
@@ -1,25 +1,24 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  any later version.
-  
-  This program is distributed in the hope that it will be useful, but WITHOUT 
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+  Intel PRO/1000 Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.
-  
+
   You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59 
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
 
 #include <asm/uaccess.h>
 
+extern char e1000_driver_name[];
+extern char e1000_driver_version[];
+
+extern int e1000_up(struct e1000_adapter *adapter);
+extern void e1000_down(struct e1000_adapter *adapter);
+extern void e1000_reinit_locked(struct e1000_adapter *adapter);
+extern void e1000_reset(struct e1000_adapter *adapter);
+extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
+extern int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
+extern int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
+extern void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
+extern void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
+extern void e1000_update_stats(struct e1000_adapter *adapter);
+
+
 struct e1000_stats {
        char stat_string[ETH_GSTRING_LEN];
        int sizeof_stat;
@@ -42,26 +56,30 @@ struct e1000_stats {
 #define E1000_STAT(m) sizeof(((struct e1000_adapter *)0)->m), \
                      offsetof(struct e1000_adapter, m)
 static const struct e1000_stats e1000_gstrings_stats[] = {
-       { "rx_packets", E1000_STAT(net_stats.rx_packets) },
-       { "tx_packets", E1000_STAT(net_stats.tx_packets) },
-       { "rx_bytes", E1000_STAT(net_stats.rx_bytes) },
-       { "tx_bytes", E1000_STAT(net_stats.tx_bytes) },
-       { "rx_errors", E1000_STAT(net_stats.rx_errors) },
-       { "tx_errors", E1000_STAT(net_stats.tx_errors) },
+       { "rx_packets", E1000_STAT(stats.gprc) },
+       { "tx_packets", E1000_STAT(stats.gptc) },
+       { "rx_bytes", E1000_STAT(stats.gorcl) },
+       { "tx_bytes", E1000_STAT(stats.gotcl) },
+       { "rx_broadcast", E1000_STAT(stats.bprc) },
+       { "tx_broadcast", E1000_STAT(stats.bptc) },
+       { "rx_multicast", E1000_STAT(stats.mprc) },
+       { "tx_multicast", E1000_STAT(stats.mptc) },
+       { "rx_errors", E1000_STAT(stats.rxerrc) },
+       { "tx_errors", E1000_STAT(stats.txerrc) },
        { "tx_dropped", E1000_STAT(net_stats.tx_dropped) },
-       { "multicast", E1000_STAT(net_stats.multicast) },
-       { "collisions", E1000_STAT(net_stats.collisions) },
-       { "rx_length_errors", E1000_STAT(net_stats.rx_length_errors) },
+       { "multicast", E1000_STAT(stats.mprc) },
+       { "collisions", E1000_STAT(stats.colc) },
+       { "rx_length_errors", E1000_STAT(stats.rlerrc) },
        { "rx_over_errors", E1000_STAT(net_stats.rx_over_errors) },
-       { "rx_crc_errors", E1000_STAT(net_stats.rx_crc_errors) },
+       { "rx_crc_errors", E1000_STAT(stats.crcerrs) },
        { "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) },
        { "rx_no_buffer_count", E1000_STAT(stats.rnbc) },
-       { "rx_missed_errors", E1000_STAT(net_stats.rx_missed_errors) },
-       { "tx_aborted_errors", E1000_STAT(net_stats.tx_aborted_errors) },
-       { "tx_carrier_errors", E1000_STAT(net_stats.tx_carrier_errors) },
+       { "rx_missed_errors", E1000_STAT(stats.mpc) },
+       { "tx_aborted_errors", E1000_STAT(stats.ecol) },
+       { "tx_carrier_errors", E1000_STAT(stats.tncrs) },
        { "tx_fifo_errors", E1000_STAT(net_stats.tx_fifo_errors) },
        { "tx_heartbeat_errors", E1000_STAT(net_stats.tx_heartbeat_errors) },
-       { "tx_window_errors", E1000_STAT(net_stats.tx_window_errors) },
+       { "tx_window_errors", E1000_STAT(stats.latecol) },
        { "tx_abort_late_coll", E1000_STAT(stats.latecol) },
        { "tx_deferred_ok", E1000_STAT(stats.dc) },
        { "tx_single_coll_ok", E1000_STAT(stats.scc) },
@@ -193,13 +211,9 @@ e1000_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
                                     ADVERTISED_FIBRE |
                                     ADVERTISED_Autoneg;
                else
-                       hw->autoneg_advertised = ADVERTISED_10baseT_Half |
-                                                 ADVERTISED_10baseT_Full |
-                                                 ADVERTISED_100baseT_Half |
-                                                 ADVERTISED_100baseT_Full |
-                                                 ADVERTISED_1000baseT_Full|
-                                                 ADVERTISED_Autoneg |
-                                                 ADVERTISED_TP;
+                       hw->autoneg_advertised = ecmd->advertising |
+                                                ADVERTISED_TP |
+                                                ADVERTISED_Autoneg;
                ecmd->advertising = hw->autoneg_advertised;
        } else
                if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
@@ -229,11 +243,11 @@ e1000_get_pauseparam(struct net_device *netdev,
        pause->autoneg =
                (adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
 
-       if (hw->fc == e1000_fc_rx_pause)
+       if (hw->fc == E1000_FC_RX_PAUSE)
                pause->rx_pause = 1;
-       else if (hw->fc == e1000_fc_tx_pause)
+       else if (hw->fc == E1000_FC_TX_PAUSE)
                pause->tx_pause = 1;
-       else if (hw->fc == e1000_fc_full) {
+       else if (hw->fc == E1000_FC_FULL) {
                pause->rx_pause = 1;
                pause->tx_pause = 1;
        }
@@ -253,13 +267,13 @@ e1000_set_pauseparam(struct net_device *netdev,
                msleep(1);
 
        if (pause->rx_pause && pause->tx_pause)
-               hw->fc = e1000_fc_full;
+               hw->fc = E1000_FC_FULL;
        else if (pause->rx_pause && !pause->tx_pause)
-               hw->fc = e1000_fc_rx_pause;
+               hw->fc = E1000_FC_RX_PAUSE;
        else if (!pause->rx_pause && pause->tx_pause)
-               hw->fc = e1000_fc_tx_pause;
+               hw->fc = E1000_FC_TX_PAUSE;
        else if (!pause->rx_pause && !pause->tx_pause)
-               hw->fc = e1000_fc_none;
+               hw->fc = E1000_FC_NONE;
 
        hw->original_fc = hw->fc;
 
@@ -632,8 +646,8 @@ e1000_set_ringparam(struct net_device *netdev,
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
        e1000_mac_type mac_type = adapter->hw.mac_type;
-       struct e1000_tx_ring *txdr, *tx_old, *tx_new;
-       struct e1000_rx_ring *rxdr, *rx_old, *rx_new;
+       struct e1000_tx_ring *txdr, *tx_old;
+       struct e1000_rx_ring *rxdr, *rx_old;
        int i, err, tx_ring_size, rx_ring_size;
 
        if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
@@ -651,23 +665,17 @@ e1000_set_ringparam(struct net_device *netdev,
        tx_old = adapter->tx_ring;
        rx_old = adapter->rx_ring;
 
-       adapter->tx_ring = kmalloc(tx_ring_size, GFP_KERNEL);
-       if (!adapter->tx_ring) {
-               err = -ENOMEM;
-               goto err_setup_rx;
-       }
-       memset(adapter->tx_ring, 0, tx_ring_size);
+       err = -ENOMEM;
+       txdr = kzalloc(tx_ring_size, GFP_KERNEL);
+       if (!txdr)
+               goto err_alloc_tx;
 
-       adapter->rx_ring = kmalloc(rx_ring_size, GFP_KERNEL);
-       if (!adapter->rx_ring) {
-               kfree(adapter->tx_ring);
-               err = -ENOMEM;
-               goto err_setup_rx;
-       }
-       memset(adapter->rx_ring, 0, rx_ring_size);
+       rxdr = kzalloc(rx_ring_size, GFP_KERNEL);
+       if (!rxdr)
+               goto err_alloc_rx;
 
-       txdr = adapter->tx_ring;
-       rxdr = adapter->rx_ring;
+       adapter->tx_ring = txdr;
+       adapter->rx_ring = rxdr;
 
        rxdr->count = max(ring->rx_pending,(uint32_t)E1000_MIN_RXD);
        rxdr->count = min(rxdr->count,(uint32_t)(mac_type < e1000_82544 ?
@@ -694,16 +702,14 @@ e1000_set_ringparam(struct net_device *netdev,
                /* save the new, restore the old in order to free it,
                 * then restore the new back again */
 
-               rx_new = adapter->rx_ring;
-               tx_new = adapter->tx_ring;
                adapter->rx_ring = rx_old;
                adapter->tx_ring = tx_old;
                e1000_free_all_rx_resources(adapter);
                e1000_free_all_tx_resources(adapter);
                kfree(tx_old);
                kfree(rx_old);
-               adapter->rx_ring = rx_new;
-               adapter->tx_ring = tx_new;
+               adapter->rx_ring = rxdr;
+               adapter->tx_ring = txdr;
                if ((err = e1000_up(adapter)))
                        goto err_setup;
        }
@@ -715,6 +721,10 @@ err_setup_tx:
 err_setup_rx:
        adapter->rx_ring = rx_old;
        adapter->tx_ring = tx_old;
+       kfree(rxdr);
+err_alloc_rx:
+       kfree(txdr);
+err_alloc_tx:
        e1000_up(adapter);
 err_setup:
        clear_bit(__E1000_RESETTING, &adapter->flags);
@@ -1610,7 +1620,7 @@ e1000_diag_test(struct net_device *netdev,
        struct e1000_adapter *adapter = netdev_priv(netdev);
        boolean_t if_running = netif_running(netdev);
 
-       set_bit(__E1000_DRIVER_TESTING, &adapter->flags);
+       set_bit(__E1000_TESTING, &adapter->flags);
        if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
                /* Offline tests */
 
@@ -1655,7 +1665,7 @@ e1000_diag_test(struct net_device *netdev,
                adapter->hw.autoneg = autoneg;
 
                e1000_reset(adapter);
-               clear_bit(__E1000_DRIVER_TESTING, &adapter->flags);
+               clear_bit(__E1000_TESTING, &adapter->flags);
                if (if_running)
                        dev_open(netdev);
        } else {
@@ -1670,7 +1680,7 @@ e1000_diag_test(struct net_device *netdev,
                data[2] = 0;
                data[3] = 0;
 
-               clear_bit(__E1000_DRIVER_TESTING, &adapter->flags);
+               clear_bit(__E1000_TESTING, &adapter->flags);
        }
        msleep_interruptible(4 * 1000);
 }
index 10b8c8c25325acd63eef44ac369c4ee94e4fa891..65077f39da69970e7e51b6854febb8998f8f527e 100644 (file)
@@ -1,25 +1,24 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  any later version.
-  
-  This program is distributed in the hope that it will be useful, but WITHOUT 
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+  Intel PRO/1000 Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.
-  
+
   You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59 
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
 
 #include "e1000_hw.h"
 
+static int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask);
+static void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask);
+static int32_t e1000_read_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *data);
+static int32_t e1000_write_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data);
+static int32_t e1000_get_software_semaphore(struct e1000_hw *hw);
+static void e1000_release_software_semaphore(struct e1000_hw *hw);
+
+static uint8_t e1000_arc_subsystem_valid(struct e1000_hw *hw);
+static int32_t e1000_check_downshift(struct e1000_hw *hw);
+static int32_t e1000_check_polarity(struct e1000_hw *hw, e1000_rev_polarity *polarity);
+static void e1000_clear_hw_cntrs(struct e1000_hw *hw);
+static void e1000_clear_vfta(struct e1000_hw *hw);
+static int32_t e1000_commit_shadow_ram(struct e1000_hw *hw);
+static int32_t e1000_config_dsp_after_link_change(struct e1000_hw *hw, boolean_t link_up);
+static int32_t e1000_config_fc_after_link_up(struct e1000_hw *hw);
+static int32_t e1000_detect_gig_phy(struct e1000_hw *hw);
+static int32_t e1000_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t bank);
+static int32_t e1000_get_auto_rd_done(struct e1000_hw *hw);
+static int32_t e1000_get_cable_length(struct e1000_hw *hw, uint16_t *min_length, uint16_t *max_length);
+static int32_t e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw);
+static int32_t e1000_get_phy_cfg_done(struct e1000_hw *hw);
+static int32_t e1000_get_software_flag(struct e1000_hw *hw);
+static int32_t e1000_ich8_cycle_init(struct e1000_hw *hw);
+static int32_t e1000_ich8_flash_cycle(struct e1000_hw *hw, uint32_t timeout);
+static int32_t e1000_id_led_init(struct e1000_hw *hw);
+static int32_t e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw, uint32_t cnf_base_addr, uint32_t cnf_size);
+static int32_t e1000_init_lcd_from_nvm(struct e1000_hw *hw);
+static void e1000_init_rx_addrs(struct e1000_hw *hw);
+static void e1000_initialize_hardware_bits(struct e1000_hw *hw);
+static boolean_t e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw);
+static int32_t e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw);
+static int32_t e1000_mng_enable_host_if(struct e1000_hw *hw);
+static int32_t e1000_mng_host_if_write(struct e1000_hw *hw, uint8_t *buffer, uint16_t length, uint16_t offset, uint8_t *sum);
+static int32_t e1000_mng_write_cmd_header(struct e1000_hw* hw, struct e1000_host_mng_command_header* hdr);
+static int32_t e1000_mng_write_commit(struct e1000_hw *hw);
+static int32_t e1000_phy_ife_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
+static int32_t e1000_phy_igp_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
+static int32_t e1000_read_eeprom_eerd(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
+static int32_t e1000_write_eeprom_eewr(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
+static int32_t e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd);
+static int32_t e1000_phy_m88_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
+static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
+static int32_t e1000_read_ich8_byte(struct e1000_hw *hw, uint32_t index, uint8_t *data);
+static int32_t e1000_verify_write_ich8_byte(struct e1000_hw *hw, uint32_t index, uint8_t byte);
+static int32_t e1000_write_ich8_byte(struct e1000_hw *hw, uint32_t index, uint8_t byte);
+static int32_t e1000_read_ich8_word(struct e1000_hw *hw, uint32_t index, uint16_t *data);
+static int32_t e1000_read_ich8_data(struct e1000_hw *hw, uint32_t index, uint32_t size, uint16_t *data);
+static int32_t e1000_write_ich8_data(struct e1000_hw *hw, uint32_t index, uint32_t size, uint16_t data);
+static int32_t e1000_read_eeprom_ich8(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
+static int32_t e1000_write_eeprom_ich8(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
+static void e1000_release_software_flag(struct e1000_hw *hw);
+static int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
+static int32_t e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active);
+static int32_t e1000_set_pci_ex_no_snoop(struct e1000_hw *hw, uint32_t no_snoop);
+static void e1000_set_pci_express_master_disable(struct e1000_hw *hw);
+static int32_t e1000_wait_autoneg(struct e1000_hw *hw);
+static void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value);
 static int32_t e1000_set_phy_type(struct e1000_hw *hw);
 static void e1000_phy_init_script(struct e1000_hw *hw);
 static int32_t e1000_setup_copper_link(struct e1000_hw *hw);
@@ -70,69 +126,10 @@ static int32_t e1000_polarity_reversal_workaround(struct e1000_hw *hw);
 static int32_t e1000_set_phy_mode(struct e1000_hw *hw);
 static int32_t e1000_host_if_read_cookie(struct e1000_hw *hw, uint8_t *buffer);
 static uint8_t e1000_calculate_mng_checksum(char *buffer, uint32_t length);
-static uint8_t e1000_arc_subsystem_valid(struct e1000_hw *hw);
-static int32_t e1000_check_downshift(struct e1000_hw *hw);
-static int32_t e1000_check_polarity(struct e1000_hw *hw, uint16_t *polarity);
-static void e1000_clear_hw_cntrs(struct e1000_hw *hw);
-static void e1000_clear_vfta(struct e1000_hw *hw);
-static int32_t e1000_commit_shadow_ram(struct e1000_hw *hw);
-static int32_t e1000_config_dsp_after_link_change(struct e1000_hw *hw,
-                                                 boolean_t link_up);
-static int32_t e1000_config_fc_after_link_up(struct e1000_hw *hw);
-static int32_t e1000_detect_gig_phy(struct e1000_hw *hw);
-static int32_t e1000_get_auto_rd_done(struct e1000_hw *hw);
-static int32_t e1000_get_cable_length(struct e1000_hw *hw,
-                                     uint16_t *min_length,
-                                     uint16_t *max_length);
-static int32_t e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw);
-static int32_t e1000_get_phy_cfg_done(struct e1000_hw *hw);
-static int32_t e1000_id_led_init(struct e1000_hw * hw);
-static void e1000_init_rx_addrs(struct e1000_hw *hw);
-static boolean_t e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw);
-static int32_t e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd);
-static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
-static int32_t e1000_read_eeprom_eerd(struct e1000_hw *hw, uint16_t offset,
-                                     uint16_t words, uint16_t *data);
-static int32_t e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active);
-static int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
-static int32_t e1000_wait_autoneg(struct e1000_hw *hw);
-
-static void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset,
-                              uint32_t value);
-
-#define E1000_WRITE_REG_IO(a, reg, val) \
-           e1000_write_reg_io((a), E1000_##reg, val)
 static int32_t e1000_configure_kmrn_for_10_100(struct e1000_hw *hw,
                                                uint16_t duplex);
 static int32_t e1000_configure_kmrn_for_1000(struct e1000_hw *hw);
 
-static int32_t e1000_erase_ich8_4k_segment(struct e1000_hw *hw,
-                                          uint32_t segment);
-static int32_t e1000_get_software_flag(struct e1000_hw *hw);
-static int32_t e1000_get_software_semaphore(struct e1000_hw *hw);
-static int32_t e1000_init_lcd_from_nvm(struct e1000_hw *hw);
-static int32_t e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw);
-static int32_t e1000_read_eeprom_ich8(struct e1000_hw *hw, uint16_t offset,
-                                     uint16_t words, uint16_t *data);
-static int32_t e1000_read_ich8_byte(struct e1000_hw *hw, uint32_t index,
-                                   uint8_t* data);
-static int32_t e1000_read_ich8_word(struct e1000_hw *hw, uint32_t index,
-                                   uint16_t *data);
-static int32_t e1000_read_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr,
-                                  uint16_t *data);
-static void e1000_release_software_flag(struct e1000_hw *hw);
-static void e1000_release_software_semaphore(struct e1000_hw *hw);
-static int32_t e1000_set_pci_ex_no_snoop(struct e1000_hw *hw,
-                                        uint32_t no_snoop);
-static int32_t e1000_verify_write_ich8_byte(struct e1000_hw *hw,
-                                           uint32_t index, uint8_t byte);
-static int32_t e1000_write_eeprom_ich8(struct e1000_hw *hw, uint16_t offset,
-                                      uint16_t words, uint16_t *data);
-static int32_t e1000_write_ich8_byte(struct e1000_hw *hw, uint32_t index,
-                                    uint8_t data);
-static int32_t e1000_write_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr,
-                                   uint16_t data);
-
 /* IGP cable length table */
 static const
 uint16_t e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] =
@@ -156,13 +153,12 @@ uint16_t e1000_igp_2_cable_length_table[IGP02E1000_AGC_LENGTH_TABLE_SIZE] =
       83, 89, 95, 100, 105, 109, 113, 116, 119, 122, 124,
       104, 109, 114, 118, 121, 124};
 
-
 /******************************************************************************
  * Set the phy type member in the hw struct.
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-int32_t
+static int32_t
 e1000_set_phy_type(struct e1000_hw *hw)
 {
     DEBUGFUNC("e1000_set_phy_type");
@@ -208,7 +204,6 @@ e1000_set_phy_type(struct e1000_hw *hw)
     return E1000_SUCCESS;
 }
 
-
 /******************************************************************************
  * IGP phy init script - initializes the GbE PHY
  *
@@ -667,19 +662,12 @@ e1000_reset_hw(struct e1000_hw *hw)
                 E1000_WRITE_FLUSH(hw);
             }
             /* fall through */
-        case e1000_82571:
-        case e1000_82572:
-        case e1000_ich8lan:
-        case e1000_80003es2lan:
+        default:
+            /* Auto read done will delay 5ms or poll based on mac type */
             ret_val = e1000_get_auto_rd_done(hw);
             if (ret_val)
-                /* We don't want to continue accessing MAC registers. */
                 return ret_val;
             break;
-        default:
-            /* Wait for EEPROM reload (it happens automatically) */
-            msleep(5);
-            break;
     }
 
     /* Disable HW ARPs on ASF enabled adapters */
@@ -721,6 +709,123 @@ e1000_reset_hw(struct e1000_hw *hw)
     return E1000_SUCCESS;
 }
 
+/******************************************************************************
+ *
+ * Initialize a number of hardware-dependent bits
+ *
+ * hw: Struct containing variables accessed by shared code
+ *
+ * This function contains hardware limitation workarounds for PCI-E adapters
+ *
+ *****************************************************************************/
+static void
+e1000_initialize_hardware_bits(struct e1000_hw *hw)
+{
+    if ((hw->mac_type >= e1000_82571) && (!hw->initialize_hw_bits_disable)) {
+        /* Settings common to all PCI-express silicon */
+        uint32_t reg_ctrl, reg_ctrl_ext;
+        uint32_t reg_tarc0, reg_tarc1;
+        uint32_t reg_tctl;
+        uint32_t reg_txdctl, reg_txdctl1;
+
+        /* link autonegotiation/sync workarounds */
+        reg_tarc0 = E1000_READ_REG(hw, TARC0);
+        reg_tarc0 &= ~((1 << 30)|(1 << 29)|(1 << 28)|(1 << 27));
+
+        /* Enable not-done TX descriptor counting */
+        reg_txdctl = E1000_READ_REG(hw, TXDCTL);
+        reg_txdctl |= E1000_TXDCTL_COUNT_DESC;
+        E1000_WRITE_REG(hw, TXDCTL, reg_txdctl);
+        reg_txdctl1 = E1000_READ_REG(hw, TXDCTL1);
+        reg_txdctl1 |= E1000_TXDCTL_COUNT_DESC;
+        E1000_WRITE_REG(hw, TXDCTL1, reg_txdctl1);
+
+        switch (hw->mac_type) {
+            case e1000_82571:
+            case e1000_82572:
+                /* Clear PHY TX compatible mode bits */
+                reg_tarc1 = E1000_READ_REG(hw, TARC1);
+                reg_tarc1 &= ~((1 << 30)|(1 << 29));
+
+                /* link autonegotiation/sync workarounds */
+                reg_tarc0 |= ((1 << 26)|(1 << 25)|(1 << 24)|(1 << 23));
+
+                /* TX ring control fixes */
+                reg_tarc1 |= ((1 << 26)|(1 << 25)|(1 << 24));
+
+                /* Multiple read bit is reversed polarity */
+                reg_tctl = E1000_READ_REG(hw, TCTL);
+                if (reg_tctl & E1000_TCTL_MULR)
+                    reg_tarc1 &= ~(1 << 28);
+                else
+                    reg_tarc1 |= (1 << 28);
+
+                E1000_WRITE_REG(hw, TARC1, reg_tarc1);
+                break;
+            case e1000_82573:
+                reg_ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+                reg_ctrl_ext &= ~(1 << 23);
+                reg_ctrl_ext |= (1 << 22);
+
+                /* TX byte count fix */
+                reg_ctrl = E1000_READ_REG(hw, CTRL);
+                reg_ctrl &= ~(1 << 29);
+
+                E1000_WRITE_REG(hw, CTRL_EXT, reg_ctrl_ext);
+                E1000_WRITE_REG(hw, CTRL, reg_ctrl);
+                break;
+            case e1000_80003es2lan:
+                /* improve small packet performace for fiber/serdes */
+                if ((hw->media_type == e1000_media_type_fiber) ||
+                    (hw->media_type == e1000_media_type_internal_serdes)) {
+                    reg_tarc0 &= ~(1 << 20);
+                }
+
+                /* Multiple read bit is reversed polarity */
+                reg_tctl = E1000_READ_REG(hw, TCTL);
+                reg_tarc1 = E1000_READ_REG(hw, TARC1);
+                if (reg_tctl & E1000_TCTL_MULR)
+                    reg_tarc1 &= ~(1 << 28);
+                else
+                    reg_tarc1 |= (1 << 28);
+
+                E1000_WRITE_REG(hw, TARC1, reg_tarc1);
+                break;
+            case e1000_ich8lan:
+                /* Reduce concurrent DMA requests to 3 from 4 */
+                if ((hw->revision_id < 3) ||
+                    ((hw->device_id != E1000_DEV_ID_ICH8_IGP_M_AMT) &&
+                     (hw->device_id != E1000_DEV_ID_ICH8_IGP_M)))
+                    reg_tarc0 |= ((1 << 29)|(1 << 28));
+
+                reg_ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+                reg_ctrl_ext |= (1 << 22);
+                E1000_WRITE_REG(hw, CTRL_EXT, reg_ctrl_ext);
+
+                /* workaround TX hang with TSO=on */
+                reg_tarc0 |= ((1 << 27)|(1 << 26)|(1 << 24)|(1 << 23));
+
+                /* Multiple read bit is reversed polarity */
+                reg_tctl = E1000_READ_REG(hw, TCTL);
+                reg_tarc1 = E1000_READ_REG(hw, TARC1);
+                if (reg_tctl & E1000_TCTL_MULR)
+                    reg_tarc1 &= ~(1 << 28);
+                else
+                    reg_tarc1 |= (1 << 28);
+
+                /* workaround TX hang with TSO=on */
+                reg_tarc1 |= ((1 << 30)|(1 << 26)|(1 << 24));
+
+                E1000_WRITE_REG(hw, TARC1, reg_tarc1);
+                break;
+            default:
+                break;
+        }
+
+        E1000_WRITE_REG(hw, TARC0, reg_tarc0);
+    }
+}
+
 /******************************************************************************
  * Performs basic configuration of the adapter.
  *
@@ -749,14 +854,13 @@ e1000_init_hw(struct e1000_hw *hw)
     DEBUGFUNC("e1000_init_hw");
 
     /* force full DMA clock frequency for 10/100 on ICH8 A0-B0 */
-    if (hw->mac_type == e1000_ich8lan) {
-        reg_data = E1000_READ_REG(hw, TARC0);
-        reg_data |= 0x30000000;
-        E1000_WRITE_REG(hw, TARC0, reg_data);
-
-        reg_data = E1000_READ_REG(hw, STATUS);
-        reg_data &= ~0x80000000;
-        E1000_WRITE_REG(hw, STATUS, reg_data);
+    if ((hw->mac_type == e1000_ich8lan) &&
+        ((hw->revision_id < 3) ||
+         ((hw->device_id != E1000_DEV_ID_ICH8_IGP_M_AMT) &&
+          (hw->device_id != E1000_DEV_ID_ICH8_IGP_M)))) {
+            reg_data = E1000_READ_REG(hw, STATUS);
+            reg_data &= ~0x80000000;
+            E1000_WRITE_REG(hw, STATUS, reg_data);
     }
 
     /* Initialize Identification LED */
@@ -769,6 +873,9 @@ e1000_init_hw(struct e1000_hw *hw)
     /* Set the media type and TBI compatibility */
     e1000_set_media_type(hw);
 
+    /* Must be called after e1000_set_media_type because media_type is used */
+    e1000_initialize_hardware_bits(hw);
+
     /* Disabling VLAN filtering. */
     DEBUGOUT("Initializing the IEEE VLAN\n");
     /* VET hardcoded to standard value and VFTA removed in ICH8 LAN */
@@ -860,17 +967,6 @@ e1000_init_hw(struct e1000_hw *hw)
     if (hw->mac_type > e1000_82544) {
         ctrl = E1000_READ_REG(hw, TXDCTL);
         ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB;
-        switch (hw->mac_type) {
-        default:
-            break;
-        case e1000_82571:
-        case e1000_82572:
-        case e1000_82573:
-        case e1000_ich8lan:
-        case e1000_80003es2lan:
-            ctrl |= E1000_TXDCTL_COUNT_DESC;
-            break;
-        }
         E1000_WRITE_REG(hw, TXDCTL, ctrl);
     }
 
@@ -908,8 +1004,6 @@ e1000_init_hw(struct e1000_hw *hw)
     case e1000_ich8lan:
         ctrl = E1000_READ_REG(hw, TXDCTL1);
         ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB;
-        if (hw->mac_type >= e1000_82571)
-            ctrl |= E1000_TXDCTL_COUNT_DESC;
         E1000_WRITE_REG(hw, TXDCTL1, ctrl);
         break;
     }
@@ -1018,11 +1112,11 @@ e1000_setup_link(struct e1000_hw *hw)
      * control setting, then the variable hw->fc will
      * be initialized based on a value in the EEPROM.
      */
-    if (hw->fc == e1000_fc_default) {
+    if (hw->fc == E1000_FC_DEFAULT) {
         switch (hw->mac_type) {
         case e1000_ich8lan:
         case e1000_82573:
-            hw->fc = e1000_fc_full;
+            hw->fc = E1000_FC_FULL;
             break;
         default:
             ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG,
@@ -1032,12 +1126,12 @@ e1000_setup_link(struct e1000_hw *hw)
                 return -E1000_ERR_EEPROM;
             }
             if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
-                hw->fc = e1000_fc_none;
+                hw->fc = E1000_FC_NONE;
             else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
                     EEPROM_WORD0F_ASM_DIR)
-                hw->fc = e1000_fc_tx_pause;
+                hw->fc = E1000_FC_TX_PAUSE;
             else
-                hw->fc = e1000_fc_full;
+                hw->fc = E1000_FC_FULL;
             break;
         }
     }
@@ -1047,10 +1141,10 @@ e1000_setup_link(struct e1000_hw *hw)
      * hub or switch with different Flow Control capabilities.
      */
     if (hw->mac_type == e1000_82542_rev2_0)
-        hw->fc &= (~e1000_fc_tx_pause);
+        hw->fc &= (~E1000_FC_TX_PAUSE);
 
     if ((hw->mac_type < e1000_82543) && (hw->report_tx_early == 1))
-        hw->fc &= (~e1000_fc_rx_pause);
+        hw->fc &= (~E1000_FC_RX_PAUSE);
 
     hw->original_fc = hw->fc;
 
@@ -1102,7 +1196,7 @@ e1000_setup_link(struct e1000_hw *hw)
      * ability to transmit pause frames in not enabled, then these
      * registers will be set to 0.
      */
-    if (!(hw->fc & e1000_fc_tx_pause)) {
+    if (!(hw->fc & E1000_FC_TX_PAUSE)) {
         E1000_WRITE_REG(hw, FCRTL, 0);
         E1000_WRITE_REG(hw, FCRTH, 0);
     } else {
@@ -1149,11 +1243,11 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
     if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572)
         E1000_WRITE_REG(hw, SCTL, E1000_DISABLE_SERDES_LOOPBACK);
 
-    /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
+    /* On adapters with a MAC newer than 82544, SWDP 1 will be
      * set when the optics detect a signal. On older adapters, it will be
      * cleared when there is a signal.  This applies to fiber media only.
-     * If we're on serdes media, adjust the output amplitude to value set in
-     * the EEPROM.
+     * If we're on serdes media, adjust the output amplitude to value
+     * set in the EEPROM.
      */
     ctrl = E1000_READ_REG(hw, CTRL);
     if (hw->media_type == e1000_media_type_fiber)
@@ -1189,11 +1283,11 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
      *      3:  Both Rx and TX flow control (symmetric) are enabled.
      */
     switch (hw->fc) {
-    case e1000_fc_none:
+    case E1000_FC_NONE:
         /* Flow control is completely disabled by a software over-ride. */
         txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
         break;
-    case e1000_fc_rx_pause:
+    case E1000_FC_RX_PAUSE:
         /* RX Flow control is enabled and TX Flow control is disabled by a
          * software over-ride. Since there really isn't a way to advertise
          * that we are capable of RX Pause ONLY, we will advertise that we
@@ -1202,13 +1296,13 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
          */
         txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
         break;
-    case e1000_fc_tx_pause:
+    case E1000_FC_TX_PAUSE:
         /* TX Flow control is enabled, and RX Flow control is disabled, by a
          * software over-ride.
          */
         txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
         break;
-    case e1000_fc_full:
+    case E1000_FC_FULL:
         /* Flow control (both RX and TX) is enabled by a software over-ride. */
         txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
         break;
@@ -2124,13 +2218,13 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw)
      *          in the EEPROM is used.
      */
     switch (hw->fc) {
-    case e1000_fc_none: /* 0 */
+    case E1000_FC_NONE: /* 0 */
         /* Flow control (RX & TX) is completely disabled by a
          * software over-ride.
          */
         mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
         break;
-    case e1000_fc_rx_pause: /* 1 */
+    case E1000_FC_RX_PAUSE: /* 1 */
         /* RX Flow control is enabled, and TX Flow control is
          * disabled, by a software over-ride.
          */
@@ -2142,14 +2236,14 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw)
          */
         mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
         break;
-    case e1000_fc_tx_pause: /* 2 */
+    case E1000_FC_TX_PAUSE: /* 2 */
         /* TX Flow control is enabled, and RX Flow control is
          * disabled, by a software over-ride.
          */
         mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
         mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
         break;
-    case e1000_fc_full: /* 3 */
+    case E1000_FC_FULL: /* 3 */
         /* Flow control (both RX and TX) is enabled by a software
          * over-ride.
          */
@@ -2193,7 +2287,7 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw)
     DEBUGFUNC("e1000_phy_force_speed_duplex");
 
     /* Turn off Flow control if we are forcing speed and duplex. */
-    hw->fc = e1000_fc_none;
+    hw->fc = E1000_FC_NONE;
 
     DEBUGOUT1("hw->fc = %d\n", hw->fc);
 
@@ -2547,18 +2641,18 @@ e1000_force_mac_fc(struct e1000_hw *hw)
      */
 
     switch (hw->fc) {
-    case e1000_fc_none:
+    case E1000_FC_NONE:
         ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
         break;
-    case e1000_fc_rx_pause:
+    case E1000_FC_RX_PAUSE:
         ctrl &= (~E1000_CTRL_TFCE);
         ctrl |= E1000_CTRL_RFCE;
         break;
-    case e1000_fc_tx_pause:
+    case E1000_FC_TX_PAUSE:
         ctrl &= (~E1000_CTRL_RFCE);
         ctrl |= E1000_CTRL_TFCE;
         break;
-    case e1000_fc_full:
+    case E1000_FC_FULL:
         ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
         break;
     default:
@@ -2657,14 +2751,14 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)
              *   LOCAL DEVICE  |   LINK PARTNER
              * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
              *-------|---------|-------|---------|--------------------
-             *   0   |    0    |  DC   |   DC    | e1000_fc_none
-             *   0   |    1    |   0   |   DC    | e1000_fc_none
-             *   0   |    1    |   1   |    0    | e1000_fc_none
-             *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
-             *   1   |    0    |   0   |   DC    | e1000_fc_none
-             *   1   |   DC    |   1   |   DC    | e1000_fc_full
-             *   1   |    1    |   0   |    0    | e1000_fc_none
-             *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
+             *   0   |    0    |  DC   |   DC    | E1000_FC_NONE
+             *   0   |    1    |   0   |   DC    | E1000_FC_NONE
+             *   0   |    1    |   1   |    0    | E1000_FC_NONE
+             *   0   |    1    |   1   |    1    | E1000_FC_TX_PAUSE
+             *   1   |    0    |   0   |   DC    | E1000_FC_NONE
+             *   1   |   DC    |   1   |   DC    | E1000_FC_FULL
+             *   1   |    1    |   0   |    0    | E1000_FC_NONE
+             *   1   |    1    |   0   |    1    | E1000_FC_RX_PAUSE
              *
              */
             /* Are both PAUSE bits set to 1?  If so, this implies
@@ -2676,7 +2770,7 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)
              *   LOCAL DEVICE  |   LINK PARTNER
              * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
              *-------|---------|-------|---------|--------------------
-             *   1   |   DC    |   1   |   DC    | e1000_fc_full
+             *   1   |   DC    |   1   |   DC    | E1000_FC_FULL
              *
              */
             if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
@@ -2687,11 +2781,11 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)
                  * ONLY. Hence, we must now check to see if we need to
                  * turn OFF  the TRANSMISSION of PAUSE frames.
                  */
-                if (hw->original_fc == e1000_fc_full) {
-                    hw->fc = e1000_fc_full;
+                if (hw->original_fc == E1000_FC_FULL) {
+                    hw->fc = E1000_FC_FULL;
                     DEBUGOUT("Flow Control = FULL.\n");
                 } else {
-                    hw->fc = e1000_fc_rx_pause;
+                    hw->fc = E1000_FC_RX_PAUSE;
                     DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
                 }
             }
@@ -2700,14 +2794,14 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)
              *   LOCAL DEVICE  |   LINK PARTNER
              * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
              *-------|---------|-------|---------|--------------------
-             *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
+             *   0   |    1    |   1   |    1    | E1000_FC_TX_PAUSE
              *
              */
             else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
                      (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
                      (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
                      (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
-                hw->fc = e1000_fc_tx_pause;
+                hw->fc = E1000_FC_TX_PAUSE;
                 DEBUGOUT("Flow Control = TX PAUSE frames only.\n");
             }
             /* For transmitting PAUSE frames ONLY.
@@ -2715,14 +2809,14 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)
              *   LOCAL DEVICE  |   LINK PARTNER
              * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
              *-------|---------|-------|---------|--------------------
-             *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
+             *   1   |    1    |   0   |    1    | E1000_FC_RX_PAUSE
              *
              */
             else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
                      (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
                      !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
                      (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
-                hw->fc = e1000_fc_rx_pause;
+                hw->fc = E1000_FC_RX_PAUSE;
                 DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
             }
             /* Per the IEEE spec, at this point flow control should be
@@ -2745,13 +2839,13 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)
              * be asked to delay transmission of packets than asking
              * our link partner to pause transmission of frames.
              */
-            else if ((hw->original_fc == e1000_fc_none ||
-                      hw->original_fc == e1000_fc_tx_pause) ||
+            else if ((hw->original_fc == E1000_FC_NONE ||
+                      hw->original_fc == E1000_FC_TX_PAUSE) ||
                       hw->fc_strict_ieee) {
-                hw->fc = e1000_fc_none;
+                hw->fc = E1000_FC_NONE;
                 DEBUGOUT("Flow Control = NONE.\n");
             } else {
-                hw->fc = e1000_fc_rx_pause;
+                hw->fc = E1000_FC_RX_PAUSE;
                 DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
             }
 
@@ -2766,7 +2860,7 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)
             }
 
             if (duplex == HALF_DUPLEX)
-                hw->fc = e1000_fc_none;
+                hw->fc = E1000_FC_NONE;
 
             /* Now we call a subroutine to actually force the MAC
              * controller to use the correct flow control settings.
@@ -3417,9 +3511,8 @@ e1000_read_phy_reg(struct e1000_hw *hw,
     return ret_val;
 }
 
-int32_t
-e1000_read_phy_reg_ex(struct e1000_hw *hw,
-                      uint32_t reg_addr,
+static int32_t
+e1000_read_phy_reg_ex(struct e1000_hw *hw, uint32_t reg_addr,
                       uint16_t *phy_data)
 {
     uint32_t i;
@@ -3499,8 +3592,7 @@ e1000_read_phy_reg_ex(struct e1000_hw *hw,
 * data - data to write to the PHY
 ******************************************************************************/
 int32_t
-e1000_write_phy_reg(struct e1000_hw *hw,
-                    uint32_t reg_addr,
+e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr,
                     uint16_t phy_data)
 {
     uint32_t ret_val;
@@ -3557,10 +3649,9 @@ e1000_write_phy_reg(struct e1000_hw *hw,
     return ret_val;
 }
 
-int32_t
-e1000_write_phy_reg_ex(struct e1000_hw *hw,
-                    uint32_t reg_addr,
-                    uint16_t phy_data)
+static int32_t
+e1000_write_phy_reg_ex(struct e1000_hw *hw, uint32_t reg_addr,
+                       uint16_t phy_data)
 {
     uint32_t i;
     uint32_t mdic = 0;
@@ -3711,7 +3802,7 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
             swfw = E1000_SWFW_PHY0_SM;
         }
         if (e1000_swfw_sync_acquire(hw, swfw)) {
-            e1000_release_software_semaphore(hw);
+            DEBUGOUT("Unable to acquire swfw sync\n");
             return -E1000_ERR_SWFW_SYNC;
         }
         /* Read the device control register and assert the E1000_CTRL_PHY_RST
@@ -3734,6 +3825,7 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
 
         if (hw->mac_type >= e1000_82571)
             mdelay(10);
+
         e1000_swfw_sync_release(hw, swfw);
     } else {
         /* Read the Extended Device Control Register, assert the PHY_RESET_DIR
@@ -3792,15 +3884,14 @@ e1000_phy_reset(struct e1000_hw *hw)
     if (ret_val)
         return E1000_SUCCESS;
 
-    switch (hw->mac_type) {
-    case e1000_82541_rev_2:
-    case e1000_82571:
-    case e1000_82572:
-    case e1000_ich8lan:
+    switch (hw->phy_type) {
+    case e1000_phy_igp:
+    case e1000_phy_igp_2:
+    case e1000_phy_igp_3:
+    case e1000_phy_ife:
         ret_val = e1000_phy_hw_reset(hw);
         if (ret_val)
             return ret_val;
-
         break;
     default:
         ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
@@ -3936,7 +4027,7 @@ e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw)
 *
 * hw - Struct containing variables accessed by shared code
 ******************************************************************************/
-int32_t
+static int32_t
 e1000_detect_gig_phy(struct e1000_hw *hw)
 {
     int32_t phy_init_status, ret_val;
@@ -3945,6 +4036,9 @@ e1000_detect_gig_phy(struct e1000_hw *hw)
 
     DEBUGFUNC("e1000_detect_gig_phy");
 
+    if (hw->phy_id != 0)
+        return E1000_SUCCESS;
+
     /* The 82571 firmware may still be configuring the PHY.  In this
      * case, we cannot access the PHY until the configuration is done.  So
      * we explicitly set the PHY values. */
@@ -4061,7 +4155,8 @@ e1000_phy_igp_get_info(struct e1000_hw *hw,
                        struct e1000_phy_info *phy_info)
 {
     int32_t ret_val;
-    uint16_t phy_data, polarity, min_length, max_length, average;
+    uint16_t phy_data, min_length, max_length, average;
+    e1000_rev_polarity polarity;
 
     DEBUGFUNC("e1000_phy_igp_get_info");
 
@@ -4086,8 +4181,8 @@ e1000_phy_igp_get_info(struct e1000_hw *hw,
     if (ret_val)
         return ret_val;
 
-    phy_info->mdix_mode = (phy_data & IGP01E1000_PSSR_MDIX) >>
-                          IGP01E1000_PSSR_MDIX_SHIFT;
+    phy_info->mdix_mode = (e1000_auto_x_mode)((phy_data & IGP01E1000_PSSR_MDIX) >>
+                          IGP01E1000_PSSR_MDIX_SHIFT);
 
     if ((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
        IGP01E1000_PSSR_SPEED_1000MBPS) {
@@ -4096,10 +4191,12 @@ e1000_phy_igp_get_info(struct e1000_hw *hw,
         if (ret_val)
             return ret_val;
 
-        phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
-                             SR_1000T_LOCAL_RX_STATUS_SHIFT;
-        phy_info->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS) >>
-                              SR_1000T_REMOTE_RX_STATUS_SHIFT;
+        phy_info->local_rx = ((phy_data & SR_1000T_LOCAL_RX_STATUS) >>
+                             SR_1000T_LOCAL_RX_STATUS_SHIFT) ?
+                             e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
+        phy_info->remote_rx = ((phy_data & SR_1000T_REMOTE_RX_STATUS) >>
+                              SR_1000T_REMOTE_RX_STATUS_SHIFT) ?
+                              e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
 
         /* Get cable length */
         ret_val = e1000_get_cable_length(hw, &min_length, &max_length);
@@ -4135,7 +4232,8 @@ e1000_phy_ife_get_info(struct e1000_hw *hw,
                        struct e1000_phy_info *phy_info)
 {
     int32_t ret_val;
-    uint16_t phy_data, polarity;
+    uint16_t phy_data;
+    e1000_rev_polarity polarity;
 
     DEBUGFUNC("e1000_phy_ife_get_info");
 
@@ -4146,8 +4244,9 @@ e1000_phy_ife_get_info(struct e1000_hw *hw,
     if (ret_val)
         return ret_val;
     phy_info->polarity_correction =
-                        (phy_data & IFE_PSC_AUTO_POLARITY_DISABLE) >>
-                        IFE_PSC_AUTO_POLARITY_DISABLE_SHIFT;
+                        ((phy_data & IFE_PSC_AUTO_POLARITY_DISABLE) >>
+                        IFE_PSC_AUTO_POLARITY_DISABLE_SHIFT) ?
+                        e1000_polarity_reversal_disabled : e1000_polarity_reversal_enabled;
 
     if (phy_info->polarity_correction == e1000_polarity_reversal_enabled) {
         ret_val = e1000_check_polarity(hw, &polarity);
@@ -4155,8 +4254,9 @@ e1000_phy_ife_get_info(struct e1000_hw *hw,
             return ret_val;
     } else {
         /* Polarity is forced. */
-        polarity = (phy_data & IFE_PSC_FORCE_POLARITY) >>
-                       IFE_PSC_FORCE_POLARITY_SHIFT;
+        polarity = ((phy_data & IFE_PSC_FORCE_POLARITY) >>
+                     IFE_PSC_FORCE_POLARITY_SHIFT) ?
+                     e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
     }
     phy_info->cable_polarity = polarity;
 
@@ -4164,9 +4264,9 @@ e1000_phy_ife_get_info(struct e1000_hw *hw,
     if (ret_val)
         return ret_val;
 
-    phy_info->mdix_mode =
-                     (phy_data & (IFE_PMC_AUTO_MDIX | IFE_PMC_FORCE_MDIX)) >>
-                     IFE_PMC_MDIX_MODE_SHIFT;
+    phy_info->mdix_mode = (e1000_auto_x_mode)
+                     ((phy_data & (IFE_PMC_AUTO_MDIX | IFE_PMC_FORCE_MDIX)) >>
+                     IFE_PMC_MDIX_MODE_SHIFT);
 
     return E1000_SUCCESS;
 }
@@ -4182,7 +4282,8 @@ e1000_phy_m88_get_info(struct e1000_hw *hw,
                        struct e1000_phy_info *phy_info)
 {
     int32_t ret_val;
-    uint16_t phy_data, polarity;
+    uint16_t phy_data;
+    e1000_rev_polarity polarity;
 
     DEBUGFUNC("e1000_phy_m88_get_info");
 
@@ -4195,11 +4296,14 @@ e1000_phy_m88_get_info(struct e1000_hw *hw,
         return ret_val;
 
     phy_info->extended_10bt_distance =
-        (phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >>
-        M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT;
+        ((phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >>
+        M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT) ?
+        e1000_10bt_ext_dist_enable_lower : e1000_10bt_ext_dist_enable_normal;
+
     phy_info->polarity_correction =
-        (phy_data & M88E1000_PSCR_POLARITY_REVERSAL) >>
-        M88E1000_PSCR_POLARITY_REVERSAL_SHIFT;
+        ((phy_data & M88E1000_PSCR_POLARITY_REVERSAL) >>
+        M88E1000_PSCR_POLARITY_REVERSAL_SHIFT) ?
+        e1000_polarity_reversal_disabled : e1000_polarity_reversal_enabled;
 
     /* Check polarity status */
     ret_val = e1000_check_polarity(hw, &polarity);
@@ -4211,15 +4315,15 @@ e1000_phy_m88_get_info(struct e1000_hw *hw,
     if (ret_val)
         return ret_val;
 
-    phy_info->mdix_mode = (phy_data & M88E1000_PSSR_MDIX) >>
-                          M88E1000_PSSR_MDIX_SHIFT;
+    phy_info->mdix_mode = (e1000_auto_x_mode)((phy_data & M88E1000_PSSR_MDIX) >>
+                          M88E1000_PSSR_MDIX_SHIFT);
 
     if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
         /* Cable Length Estimation and Local/Remote Receiver Information
          * are only valid at 1000 Mbps.
          */
         if (hw->phy_type != e1000_phy_gg82563) {
-            phy_info->cable_length = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
+            phy_info->cable_length = (e1000_cable_length)((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
                                       M88E1000_PSSR_CABLE_LENGTH_SHIFT);
         } else {
             ret_val = e1000_read_phy_reg(hw, GG82563_PHY_DSP_DISTANCE,
@@ -4227,18 +4331,20 @@ e1000_phy_m88_get_info(struct e1000_hw *hw,
             if (ret_val)
                 return ret_val;
 
-            phy_info->cable_length = phy_data & GG82563_DSPD_CABLE_LENGTH;
+            phy_info->cable_length = (e1000_cable_length)(phy_data & GG82563_DSPD_CABLE_LENGTH);
         }
 
         ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
         if (ret_val)
             return ret_val;
 
-        phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
-                             SR_1000T_LOCAL_RX_STATUS_SHIFT;
+        phy_info->local_rx = ((phy_data & SR_1000T_LOCAL_RX_STATUS) >>
+                             SR_1000T_LOCAL_RX_STATUS_SHIFT) ?
+                             e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
+        phy_info->remote_rx = ((phy_data & SR_1000T_REMOTE_RX_STATUS) >>
+                              SR_1000T_REMOTE_RX_STATUS_SHIFT) ?
+                              e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
 
-        phy_info->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS) >>
-                              SR_1000T_REMOTE_RX_STATUS_SHIFT;
     }
 
     return E1000_SUCCESS;
@@ -4441,7 +4547,7 @@ e1000_init_eeprom_params(struct e1000_hw *hw)
         eeprom->use_eewr = FALSE;
         break;
     case e1000_ich8lan:
-    {
+        {
         int32_t  i = 0;
         uint32_t flash_size = E1000_READ_ICH8_REG(hw, ICH8_FLASH_GFPREG);
 
@@ -4468,7 +4574,7 @@ e1000_init_eeprom_params(struct e1000_hw *hw)
         hw->flash_bank_size /= 2 * sizeof(uint16_t);
 
         break;
-    }
+        }
     default:
         break;
     }
@@ -4800,7 +4906,7 @@ e1000_release_eeprom(struct e1000_hw *hw)
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-int32_t
+static int32_t
 e1000_spi_eeprom_ready(struct e1000_hw *hw)
 {
     uint16_t retry_count = 0;
@@ -4854,44 +4960,43 @@ e1000_read_eeprom(struct e1000_hw *hw,
 {
     struct e1000_eeprom_info *eeprom = &hw->eeprom;
     uint32_t i = 0;
-    int32_t ret_val;
 
     DEBUGFUNC("e1000_read_eeprom");
 
+    /* If eeprom is not yet detected, do so now */
+    if (eeprom->word_size == 0)
+        e1000_init_eeprom_params(hw);
+
     /* A check for invalid values:  offset too large, too many words, and not
      * enough words.
      */
     if ((offset >= eeprom->word_size) || (words > eeprom->word_size - offset) ||
        (words == 0)) {
-        DEBUGOUT("\"words\" parameter out of bounds\n");
+        DEBUGOUT2("\"words\" parameter out of bounds. Words = %d, size = %d\n", offset, eeprom->word_size);
         return -E1000_ERR_EEPROM;
     }
 
-    /* FLASH reads without acquiring the semaphore are safe */
+    /* EEPROM's that don't use EERD to read require us to bit-bang the SPI
+     * directly. In this case, we need to acquire the EEPROM so that
+     * FW or other port software does not interrupt.
+     */
     if (e1000_is_onboard_nvm_eeprom(hw) == TRUE &&
         hw->eeprom.use_eerd == FALSE) {
-        switch (hw->mac_type) {
-        case e1000_80003es2lan:
-            break;
-        default:
-            /* Prepare the EEPROM for reading  */
-            if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
-                return -E1000_ERR_EEPROM;
-            break;
-        }
+        /* Prepare the EEPROM for bit-bang reading */
+        if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
+            return -E1000_ERR_EEPROM;
     }
 
-    if (eeprom->use_eerd == TRUE) {
-        ret_val = e1000_read_eeprom_eerd(hw, offset, words, data);
-        if ((e1000_is_onboard_nvm_eeprom(hw) == TRUE) ||
-            (hw->mac_type != e1000_82573))
-            e1000_release_eeprom(hw);
-        return ret_val;
-    }
+    /* Eerd register EEPROM access requires no eeprom aquire/release */
+    if (eeprom->use_eerd == TRUE)
+        return e1000_read_eeprom_eerd(hw, offset, words, data);
 
+    /* ICH EEPROM access is done via the ICH flash controller */
     if (eeprom->type == e1000_eeprom_ich8)
         return e1000_read_eeprom_ich8(hw, offset, words, data);
 
+    /* Set up the SPI or Microwire EEPROM for bit-bang reading.  We have
+     * acquired the EEPROM at this point, so any returns should relase it */
     if (eeprom->type == e1000_eeprom_spi) {
         uint16_t word_in;
         uint8_t read_opcode = EEPROM_READ_OPCODE_SPI;
@@ -5206,6 +5311,10 @@ e1000_write_eeprom(struct e1000_hw *hw,
 
     DEBUGFUNC("e1000_write_eeprom");
 
+    /* If eeprom is not yet detected, do so now */
+    if (eeprom->word_size == 0)
+        e1000_init_eeprom_params(hw);
+
     /* A check for invalid values:  offset too large, too many words, and not
      * enough words.
      */
@@ -5248,7 +5357,7 @@ e1000_write_eeprom(struct e1000_hw *hw,
  * data - pointer to array of 8 bit words to be written to the EEPROM
  *
  *****************************************************************************/
-int32_t
+static int32_t
 e1000_write_eeprom_spi(struct e1000_hw *hw,
                        uint16_t offset,
                        uint16_t words,
@@ -5314,7 +5423,7 @@ e1000_write_eeprom_spi(struct e1000_hw *hw,
  * data - pointer to array of 16 bit words to be written to the EEPROM
  *
  *****************************************************************************/
-int32_t
+static int32_t
 e1000_write_eeprom_microwire(struct e1000_hw *hw,
                              uint16_t offset,
                              uint16_t words,
@@ -5411,10 +5520,8 @@ e1000_commit_shadow_ram(struct e1000_hw *hw)
     int32_t error = E1000_SUCCESS;
     uint32_t old_bank_offset = 0;
     uint32_t new_bank_offset = 0;
-    uint32_t sector_retries = 0;
     uint8_t low_byte = 0;
     uint8_t high_byte = 0;
-    uint8_t temp_byte = 0;
     boolean_t sector_write_failed = FALSE;
 
     if (hw->mac_type == e1000_82573) {
@@ -5467,41 +5574,46 @@ e1000_commit_shadow_ram(struct e1000_hw *hw)
             e1000_erase_ich8_4k_segment(hw, 0);
         }
 
-        do {
-            sector_write_failed = FALSE;
-            /* Loop for every byte in the shadow RAM,
-             * which is in units of words. */
-            for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
-                /* Determine whether to write the value stored
-                 * in the other NVM bank or a modified value stored
-                 * in the shadow RAM */
-                if (hw->eeprom_shadow_ram[i].modified == TRUE) {
-                    low_byte = (uint8_t)hw->eeprom_shadow_ram[i].eeprom_word;
-                    e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset,
-                                         &temp_byte);
-                    udelay(100);
-                    error = e1000_verify_write_ich8_byte(hw,
-                                                 (i << 1) + new_bank_offset,
-                                                 low_byte);
-                    if (error != E1000_SUCCESS)
-                        sector_write_failed = TRUE;
+        sector_write_failed = FALSE;
+        /* Loop for every byte in the shadow RAM,
+         * which is in units of words. */
+        for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
+            /* Determine whether to write the value stored
+             * in the other NVM bank or a modified value stored
+             * in the shadow RAM */
+            if (hw->eeprom_shadow_ram[i].modified == TRUE) {
+                low_byte = (uint8_t)hw->eeprom_shadow_ram[i].eeprom_word;
+                udelay(100);
+                error = e1000_verify_write_ich8_byte(hw,
+                            (i << 1) + new_bank_offset, low_byte);
+
+                if (error != E1000_SUCCESS)
+                    sector_write_failed = TRUE;
+                else {
                     high_byte =
                         (uint8_t)(hw->eeprom_shadow_ram[i].eeprom_word >> 8);
-                    e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset + 1,
-                                         &temp_byte);
-                    udelay(100);
-                } else {
-                    e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset,
-                                         &low_byte);
                     udelay(100);
-                    error = e1000_verify_write_ich8_byte(hw,
-                                 (i << 1) + new_bank_offset, low_byte);
-                    if (error != E1000_SUCCESS)
-                        sector_write_failed = TRUE;
+                }
+            } else {
+                e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset,
+                                     &low_byte);
+                udelay(100);
+                error = e1000_verify_write_ich8_byte(hw,
+                            (i << 1) + new_bank_offset, low_byte);
+
+                if (error != E1000_SUCCESS)
+                    sector_write_failed = TRUE;
+                else {
                     e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset + 1,
                                          &high_byte);
+                    udelay(100);
                 }
+            }
 
+            /* If the write of the low byte was successful, go ahread and
+             * write the high byte while checking to make sure that if it
+             * is the signature byte, then it is handled properly */
+            if (sector_write_failed == FALSE) {
                 /* If the word is 0x13, then make sure the signature bits
                  * (15:14) are 11b until the commit has completed.
                  * This will allow us to write 10b which indicates the
@@ -5512,45 +5624,45 @@ e1000_commit_shadow_ram(struct e1000_hw *hw)
                     high_byte = E1000_ICH8_NVM_SIG_MASK | high_byte;
 
                 error = e1000_verify_write_ich8_byte(hw,
-                             (i << 1) + new_bank_offset + 1, high_byte);
+                            (i << 1) + new_bank_offset + 1, high_byte);
                 if (error != E1000_SUCCESS)
                     sector_write_failed = TRUE;
 
-                if (sector_write_failed == FALSE) {
-                    /* Clear the now not used entry in the cache */
-                    hw->eeprom_shadow_ram[i].modified = FALSE;
-                    hw->eeprom_shadow_ram[i].eeprom_word = 0xFFFF;
-                }
+            } else {
+                /* If the write failed then break from the loop and
+                 * return an error */
+                break;
             }
+        }
 
-            /* Don't bother writing the segment valid bits if sector
-             * programming failed. */
-            if (sector_write_failed == FALSE) {
-                /* Finally validate the new segment by setting bit 15:14
-                 * to 10b in word 0x13 , this can be done without an
-                 * erase as well since these bits are 11 to start with
-                 * and we need to change bit 14 to 0b */
-                e1000_read_ich8_byte(hw,
-                    E1000_ICH8_NVM_SIG_WORD * 2 + 1 + new_bank_offset,
-                    &high_byte);
-                high_byte &= 0xBF;
+        /* Don't bother writing the segment valid bits if sector
+         * programming failed. */
+        if (sector_write_failed == FALSE) {
+            /* Finally validate the new segment by setting bit 15:14
+             * to 10b in word 0x13 , this can be done without an
+             * erase as well since these bits are 11 to start with
+             * and we need to change bit 14 to 0b */
+            e1000_read_ich8_byte(hw,
+                                 E1000_ICH8_NVM_SIG_WORD * 2 + 1 + new_bank_offset,
+                                 &high_byte);
+            high_byte &= 0xBF;
+            error = e1000_verify_write_ich8_byte(hw,
+                        E1000_ICH8_NVM_SIG_WORD * 2 + 1 + new_bank_offset, high_byte);
+            /* And invalidate the previously valid segment by setting
+             * its signature word (0x13) high_byte to 0b. This can be
+             * done without an erase because flash erase sets all bits
+             * to 1's. We can write 1's to 0's without an erase */
+            if (error == E1000_SUCCESS) {
                 error = e1000_verify_write_ich8_byte(hw,
-                            E1000_ICH8_NVM_SIG_WORD * 2 + 1 + new_bank_offset,
-                            high_byte);
-                if (error != E1000_SUCCESS)
-                    sector_write_failed = TRUE;
+                            E1000_ICH8_NVM_SIG_WORD * 2 + 1 + old_bank_offset, 0);
+            }
 
-                /* And invalidate the previously valid segment by setting
-                 * its signature word (0x13) high_byte to 0b. This can be
-                 * done without an erase because flash erase sets all bits
-                 * to 1's. We can write 1's to 0's without an erase */
-                error = e1000_verify_write_ich8_byte(hw,
-                            E1000_ICH8_NVM_SIG_WORD * 2 + 1 + old_bank_offset,
-                            0);
-                if (error != E1000_SUCCESS)
-                    sector_write_failed = TRUE;
+            /* Clear the now not used entry in the cache */
+            for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
+                hw->eeprom_shadow_ram[i].modified = FALSE;
+                hw->eeprom_shadow_ram[i].eeprom_word = 0xFFFF;
             }
-        } while (++sector_retries < 10 && sector_write_failed == TRUE);
+        }
     }
 
     return error;
@@ -5639,99 +5751,6 @@ e1000_init_rx_addrs(struct e1000_hw *hw)
     }
 }
 
-/******************************************************************************
- * Updates the MAC's list of multicast addresses.
- *
- * hw - Struct containing variables accessed by shared code
- * mc_addr_list - the list of new multicast addresses
- * mc_addr_count - number of addresses
- * pad - number of bytes between addresses in the list
- * rar_used_count - offset where to start adding mc addresses into the RAR's
- *
- * The given list replaces any existing list. Clears the last 15 receive
- * address registers and the multicast table. Uses receive address registers
- * for the first 15 multicast addresses, and hashes the rest into the
- * multicast table.
- *****************************************************************************/
-#if 0
-void
-e1000_mc_addr_list_update(struct e1000_hw *hw,
-                          uint8_t *mc_addr_list,
-                          uint32_t mc_addr_count,
-                          uint32_t pad,
-                          uint32_t rar_used_count)
-{
-    uint32_t hash_value;
-    uint32_t i;
-    uint32_t num_rar_entry;
-    uint32_t num_mta_entry;
-
-    DEBUGFUNC("e1000_mc_addr_list_update");
-
-    /* Set the new number of MC addresses that we are being requested to use. */
-    hw->num_mc_addrs = mc_addr_count;
-
-    /* Clear RAR[1-15] */
-    DEBUGOUT(" Clearing RAR[1-15]\n");
-    num_rar_entry = E1000_RAR_ENTRIES;
-    if (hw->mac_type == e1000_ich8lan)
-        num_rar_entry = E1000_RAR_ENTRIES_ICH8LAN;
-    /* Reserve a spot for the Locally Administered Address to work around
-     * an 82571 issue in which a reset on one port will reload the MAC on
-     * the other port. */
-    if ((hw->mac_type == e1000_82571) && (hw->laa_is_present == TRUE))
-        num_rar_entry -= 1;
-
-    for (i = rar_used_count; i < num_rar_entry; i++) {
-        E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
-        E1000_WRITE_FLUSH(hw);
-        E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
-        E1000_WRITE_FLUSH(hw);
-    }
-
-    /* Clear the MTA */
-    DEBUGOUT(" Clearing MTA\n");
-    num_mta_entry = E1000_NUM_MTA_REGISTERS;
-    if (hw->mac_type == e1000_ich8lan)
-        num_mta_entry = E1000_NUM_MTA_REGISTERS_ICH8LAN;
-    for (i = 0; i < num_mta_entry; i++) {
-        E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
-        E1000_WRITE_FLUSH(hw);
-    }
-
-    /* Add the new addresses */
-    for (i = 0; i < mc_addr_count; i++) {
-        DEBUGOUT(" Adding the multicast addresses:\n");
-        DEBUGOUT7(" MC Addr #%d =%.2X %.2X %.2X %.2X %.2X %.2X\n", i,
-                  mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad)],
-                  mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 1],
-                  mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 2],
-                  mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 3],
-                  mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 4],
-                  mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad) + 5]);
-
-        hash_value = e1000_hash_mc_addr(hw,
-                                        mc_addr_list +
-                                        (i * (ETH_LENGTH_OF_ADDRESS + pad)));
-
-        DEBUGOUT1(" Hash value = 0x%03X\n", hash_value);
-
-        /* Place this multicast address in the RAR if there is room, *
-         * else put it in the MTA
-         */
-        if (rar_used_count < num_rar_entry) {
-            e1000_rar_set(hw,
-                          mc_addr_list + (i * (ETH_LENGTH_OF_ADDRESS + pad)),
-                          rar_used_count);
-            rar_used_count++;
-        } else {
-            e1000_mta_set(hw, hash_value);
-        }
-    }
-    DEBUGOUT("MC Update Complete\n");
-}
-#endif  /*  0  */
-
 /******************************************************************************
  * Hashes an address to determine its location in the multicast table
  *
@@ -6290,7 +6309,7 @@ e1000_led_off(struct e1000_hw *hw)
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void
+static void
 e1000_clear_hw_cntrs(struct e1000_hw *hw)
 {
     volatile uint32_t temp;
@@ -6539,6 +6558,8 @@ e1000_tbi_adjust_stats(struct e1000_hw *hw,
 void
 e1000_get_bus_info(struct e1000_hw *hw)
 {
+    int32_t ret_val;
+    uint16_t pci_ex_link_status;
     uint32_t status;
 
     switch (hw->mac_type) {
@@ -6548,18 +6569,25 @@ e1000_get_bus_info(struct e1000_hw *hw)
         hw->bus_speed = e1000_bus_speed_unknown;
         hw->bus_width = e1000_bus_width_unknown;
         break;
+    case e1000_82571:
     case e1000_82572:
     case e1000_82573:
+    case e1000_80003es2lan:
         hw->bus_type = e1000_bus_type_pci_express;
         hw->bus_speed = e1000_bus_speed_2500;
-        hw->bus_width = e1000_bus_width_pciex_1;
+        ret_val = e1000_read_pcie_cap_reg(hw,
+                                      PCI_EX_LINK_STATUS,
+                                      &pci_ex_link_status);
+        if (ret_val)
+            hw->bus_width = e1000_bus_width_unknown;
+        else
+            hw->bus_width = (pci_ex_link_status & PCI_EX_LINK_WIDTH_MASK) >>
+                          PCI_EX_LINK_WIDTH_SHIFT;
         break;
-    case e1000_82571:
     case e1000_ich8lan:
-    case e1000_80003es2lan:
         hw->bus_type = e1000_bus_type_pci_express;
         hw->bus_speed = e1000_bus_speed_2500;
-        hw->bus_width = e1000_bus_width_pciex_4;
+        hw->bus_width = e1000_bus_width_pciex_1;
         break;
     default:
         status = E1000_READ_REG(hw, STATUS);
@@ -6593,25 +6621,6 @@ e1000_get_bus_info(struct e1000_hw *hw)
         break;
     }
 }
-/******************************************************************************
- * Reads a value from one of the devices registers using port I/O (as opposed
- * memory mapped I/O). Only 82544 and newer devices support port I/O.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - offset to read from
- *****************************************************************************/
-#if 0
-uint32_t
-e1000_read_reg_io(struct e1000_hw *hw,
-                  uint32_t offset)
-{
-    unsigned long io_addr = hw->io_base;
-    unsigned long io_data = hw->io_base + 4;
-
-    e1000_io_write(hw, io_addr, offset);
-    return e1000_io_read(hw, io_data);
-}
-#endif  /*  0  */
 
 /******************************************************************************
  * Writes a value to one of the devices registers using port I/O (as opposed to
@@ -6633,7 +6642,6 @@ e1000_write_reg_io(struct e1000_hw *hw,
     e1000_io_write(hw, io_data, value);
 }
 
-
 /******************************************************************************
  * Estimates the cable length.
  *
@@ -6842,7 +6850,7 @@ e1000_get_cable_length(struct e1000_hw *hw,
  *****************************************************************************/
 static int32_t
 e1000_check_polarity(struct e1000_hw *hw,
-                     uint16_t *polarity)
+                     e1000_rev_polarity *polarity)
 {
     int32_t ret_val;
     uint16_t phy_data;
@@ -6856,8 +6864,10 @@ e1000_check_polarity(struct e1000_hw *hw,
                                      &phy_data);
         if (ret_val)
             return ret_val;
-        *polarity = (phy_data & M88E1000_PSSR_REV_POLARITY) >>
-                    M88E1000_PSSR_REV_POLARITY_SHIFT;
+        *polarity = ((phy_data & M88E1000_PSSR_REV_POLARITY) >>
+                     M88E1000_PSSR_REV_POLARITY_SHIFT) ?
+                     e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
+
     } else if (hw->phy_type == e1000_phy_igp ||
               hw->phy_type == e1000_phy_igp_3 ||
               hw->phy_type == e1000_phy_igp_2) {
@@ -6879,19 +6889,22 @@ e1000_check_polarity(struct e1000_hw *hw,
                 return ret_val;
 
             /* Check the polarity bits */
-            *polarity = (phy_data & IGP01E1000_PHY_POLARITY_MASK) ? 1 : 0;
+            *polarity = (phy_data & IGP01E1000_PHY_POLARITY_MASK) ?
+                         e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
         } else {
             /* For 10 Mbps, read the polarity bit in the status register. (for
              * 100 Mbps this bit is always 0) */
-            *polarity = phy_data & IGP01E1000_PSSR_POLARITY_REVERSED;
+            *polarity = (phy_data & IGP01E1000_PSSR_POLARITY_REVERSED) ?
+                         e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
         }
     } else if (hw->phy_type == e1000_phy_ife) {
         ret_val = e1000_read_phy_reg(hw, IFE_PHY_EXTENDED_STATUS_CONTROL,
                                      &phy_data);
         if (ret_val)
             return ret_val;
-        *polarity = (phy_data & IFE_PESC_POLARITY_REVERSED) >>
-                           IFE_PESC_POLARITY_REVERSED_SHIFT;
+        *polarity = ((phy_data & IFE_PESC_POLARITY_REVERSED) >>
+                     IFE_PESC_POLARITY_REVERSED_SHIFT) ?
+                     e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
     }
     return E1000_SUCCESS;
 }
@@ -7259,7 +7272,7 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw,
         } else if (hw->smart_speed == e1000_smart_speed_off) {
             ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
                                          &phy_data);
-           if (ret_val)
+            if (ret_val)
                 return ret_val;
 
             phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
@@ -7369,7 +7382,7 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw,
         } else if (hw->smart_speed == e1000_smart_speed_off) {
             ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
                                          &phy_data);
-           if (ret_val)
+            if (ret_val)
                 return ret_val;
 
             phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
@@ -7475,7 +7488,7 @@ e1000_set_vco_speed(struct e1000_hw *hw)
  *
  * returns: - E1000_SUCCESS .
  ****************************************************************************/
-int32_t
+static int32_t
 e1000_host_if_read_cookie(struct e1000_hw * hw, uint8_t *buffer)
 {
     uint8_t i;
@@ -7686,7 +7699,7 @@ e1000_check_mng_mode(struct e1000_hw *hw)
  ****************************************************************************/
 int32_t
 e1000_mng_write_dhcp_info(struct e1000_hw * hw, uint8_t *buffer,
-                         uint16_t length)
+                          uint16_t length)
 {
     int32_t ret_val;
     struct e1000_host_mng_command_header hdr;
@@ -7716,7 +7729,7 @@ e1000_mng_write_dhcp_info(struct e1000_hw * hw, uint8_t *buffer,
  *
  * returns  - checksum of buffer contents.
  ****************************************************************************/
-uint8_t
+static uint8_t
 e1000_calculate_mng_checksum(char *buffer, uint32_t length)
 {
     uint8_t sum = 0;
@@ -7914,32 +7927,6 @@ e1000_set_pci_express_master_disable(struct e1000_hw *hw)
     E1000_WRITE_REG(hw, CTRL, ctrl);
 }
 
-/***************************************************************************
- *
- * Enables PCI-Express master access.
- *
- * hw: Struct containing variables accessed by shared code
- *
- * returns: - none.
- *
- ***************************************************************************/
-#if 0
-void
-e1000_enable_pciex_master(struct e1000_hw *hw)
-{
-    uint32_t ctrl;
-
-    DEBUGFUNC("e1000_enable_pciex_master");
-
-    if (hw->bus_type != e1000_bus_type_pci_express)
-        return;
-
-    ctrl = E1000_READ_REG(hw, CTRL);
-    ctrl &= ~E1000_CTRL_GIO_MASTER_DISABLE;
-    E1000_WRITE_REG(hw, CTRL, ctrl);
-}
-#endif  /*  0  */
-
 /*******************************************************************************
  *
  * Disables PCI-Express master access and verifies there are no pending requests
@@ -8063,7 +8050,6 @@ e1000_get_phy_cfg_done(struct e1000_hw *hw)
                 msleep(1);
             timeout--;
         }
-
         if (!timeout) {
             DEBUGOUT("MNG configuration cycle has not completed.\n");
             return -E1000_ERR_RESET;
@@ -8172,8 +8158,9 @@ e1000_get_software_semaphore(struct e1000_hw *hw)
 
     DEBUGFUNC("e1000_get_software_semaphore");
 
-    if (hw->mac_type != e1000_80003es2lan)
+    if (hw->mac_type != e1000_80003es2lan) {
         return E1000_SUCCESS;
+    }
 
     while (timeout) {
         swsm = E1000_READ_REG(hw, SWSM);
@@ -8206,8 +8193,9 @@ e1000_release_software_semaphore(struct e1000_hw *hw)
 
     DEBUGFUNC("e1000_release_software_semaphore");
 
-    if (hw->mac_type != e1000_80003es2lan)
+    if (hw->mac_type != e1000_80003es2lan) {
         return;
+    }
 
     swsm = E1000_READ_REG(hw, SWSM);
     /* Release the SW semaphores.*/
@@ -8241,7 +8229,7 @@ e1000_check_phy_reset_block(struct e1000_hw *hw)
     if (hw->mac_type > e1000_82547_rev_2)
         manc = E1000_READ_REG(hw, MANC);
     return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ?
-           E1000_BLK_PHY_RESET : E1000_SUCCESS;
+        E1000_BLK_PHY_RESET : E1000_SUCCESS;
 }
 
 static uint8_t
@@ -8377,66 +8365,6 @@ e1000_release_software_flag(struct e1000_hw *hw)
     return;
 }
 
-/***************************************************************************
- *
- * Disable dynamic power down mode in ife PHY.
- * It can be used to workaround band-gap problem.
- *
- * hw: Struct containing variables accessed by shared code
- *
- ***************************************************************************/
-#if 0
-int32_t
-e1000_ife_disable_dynamic_power_down(struct e1000_hw *hw)
-{
-    uint16_t phy_data;
-    int32_t ret_val = E1000_SUCCESS;
-
-    DEBUGFUNC("e1000_ife_disable_dynamic_power_down");
-
-    if (hw->phy_type == e1000_phy_ife) {
-        ret_val = e1000_read_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL, &phy_data);
-        if (ret_val)
-            return ret_val;
-
-        phy_data |=  IFE_PSC_DISABLE_DYNAMIC_POWER_DOWN;
-        ret_val = e1000_write_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL, phy_data);
-    }
-
-    return ret_val;
-}
-#endif  /*  0  */
-
-/***************************************************************************
- *
- * Enable dynamic power down mode in ife PHY.
- * It can be used to workaround band-gap problem.
- *
- * hw: Struct containing variables accessed by shared code
- *
- ***************************************************************************/
-#if 0
-int32_t
-e1000_ife_enable_dynamic_power_down(struct e1000_hw *hw)
-{
-    uint16_t phy_data;
-    int32_t ret_val = E1000_SUCCESS;
-
-    DEBUGFUNC("e1000_ife_enable_dynamic_power_down");
-
-    if (hw->phy_type == e1000_phy_ife) {
-        ret_val = e1000_read_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL, &phy_data);
-        if (ret_val)
-            return ret_val;
-
-        phy_data &=  ~IFE_PSC_DISABLE_DYNAMIC_POWER_DOWN;
-        ret_val = e1000_write_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL, phy_data);
-    }
-
-    return ret_val;
-}
-#endif  /*  0  */
-
 /******************************************************************************
  * Reads a 16 bit word or words from the EEPROM using the ICH8's flash access
  * register.
@@ -8832,20 +8760,22 @@ static int32_t
 e1000_verify_write_ich8_byte(struct e1000_hw *hw, uint32_t index, uint8_t byte)
 {
     int32_t error = E1000_SUCCESS;
-    int32_t program_retries;
-    uint8_t temp_byte;
+    int32_t program_retries = 0;
 
-    e1000_write_ich8_byte(hw, index, byte);
-    udelay(100);
+    DEBUGOUT2("Byte := %2.2X Offset := %d\n", byte, index);
 
-    for (program_retries = 0; program_retries < 100; program_retries++) {
-        e1000_read_ich8_byte(hw, index, &temp_byte);
-        if (temp_byte == byte)
-            break;
-        udelay(10);
-        e1000_write_ich8_byte(hw, index, byte);
-        udelay(100);
+    error = e1000_write_ich8_byte(hw, index, byte);
+
+    if (error != E1000_SUCCESS) {
+        for (program_retries = 0; program_retries < 100; program_retries++) {
+            DEBUGOUT2("Retrying \t Byte := %2.2X Offset := %d\n", byte, index);
+            error = e1000_write_ich8_byte(hw, index, byte);
+            udelay(100);
+            if (error == E1000_SUCCESS)
+                break;
+        }
     }
+
     if (program_retries == 100)
         error = E1000_ERR_EEPROM;
 
@@ -8886,39 +8816,27 @@ e1000_read_ich8_word(struct e1000_hw *hw, uint32_t index, uint16_t *data)
 }
 
 /******************************************************************************
- * Writes a word to the NVM using the ICH8 flash access registers.
+ * Erases the bank specified. Each bank may be a 4, 8 or 64k block. Banks are 0
+ * based.
  *
  * hw - pointer to e1000_hw structure
- * index - The starting byte index of the word to read.
- * data - The word to write to the NVM.
- *****************************************************************************/
-#if 0
-int32_t
-e1000_write_ich8_word(struct e1000_hw *hw, uint32_t index, uint16_t data)
-{
-    int32_t status = E1000_SUCCESS;
-    status = e1000_write_ich8_data(hw, index, 2, data);
-    return status;
-}
-#endif  /*  0  */
-
-/******************************************************************************
- * Erases the bank specified. Each bank is a 4k block. Segments are 0 based.
- * segment N is 4096 * N + flash_reg_addr.
+ * bank - 0 for first bank, 1 for second bank
  *
- * hw - pointer to e1000_hw structure
- * segment - 0 for first segment, 1 for second segment, etc.
+ * Note that this function may actually erase as much as 8 or 64 KBytes.  The
+ * amount of NVM used in each bank is a *minimum* of 4 KBytes, but in fact the
+ * bank size may be 4, 8 or 64 KBytes
  *****************************************************************************/
-static int32_t
-e1000_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t segment)
+int32_t
+e1000_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t bank)
 {
     union ich8_hws_flash_status hsfsts;
     union ich8_hws_flash_ctrl hsflctl;
     uint32_t flash_linear_address;
     int32_t  count = 0;
     int32_t  error = E1000_ERR_EEPROM;
-    int32_t  iteration, seg_size;
-    int32_t  sector_size;
+    int32_t  iteration;
+    int32_t  sub_sector_size = 0;
+    int32_t  bank_size;
     int32_t  j = 0;
     int32_t  error_flag = 0;
 
@@ -8927,22 +8845,27 @@ e1000_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t segment)
     /* Determine HW Sector size: Read BERASE bits of Hw flash Status register */
     /* 00: The Hw sector is 256 bytes, hence we need to erase 16
      *     consecutive sectors.  The start index for the nth Hw sector can be
-     *     calculated as = segment * 4096 + n * 256
+     *     calculated as bank * 4096 + n * 256
      * 01: The Hw sector is 4K bytes, hence we need to erase 1 sector.
      *     The start index for the nth Hw sector can be calculated
-     *     as = segment * 4096
-     * 10: Error condition
-     * 11: The Hw sector size is much bigger than the size asked to
-     *     erase...error condition */
+     *     as bank * 4096
+     * 10: The HW sector is 8K bytes
+     * 11: The Hw sector size is 64K bytes */
     if (hsfsts.hsf_status.berasesz == 0x0) {
         /* Hw sector size 256 */
-        sector_size = seg_size = ICH8_FLASH_SEG_SIZE_256;
+        sub_sector_size = ICH8_FLASH_SEG_SIZE_256;
+        bank_size = ICH8_FLASH_SECTOR_SIZE;
         iteration = ICH8_FLASH_SECTOR_SIZE / ICH8_FLASH_SEG_SIZE_256;
     } else if (hsfsts.hsf_status.berasesz == 0x1) {
-        sector_size = seg_size = ICH8_FLASH_SEG_SIZE_4K;
+        bank_size = ICH8_FLASH_SEG_SIZE_4K;
+        iteration = 1;
+    } else if (hw->mac_type != e1000_ich8lan &&
+               hsfsts.hsf_status.berasesz == 0x2) {
+        /* 8K erase size invalid for ICH8 - added in for ICH9 */
+        bank_size = ICH9_FLASH_SEG_SIZE_8K;
         iteration = 1;
     } else if (hsfsts.hsf_status.berasesz == 0x3) {
-        sector_size = seg_size = ICH8_FLASH_SEG_SIZE_64K;
+        bank_size = ICH8_FLASH_SEG_SIZE_64K;
         iteration = 1;
     } else {
         return error;
@@ -8966,16 +8889,15 @@ e1000_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t segment)
 
             /* Write the last 24 bits of an index within the block into Flash
              * Linear address field in Flash Address.  This probably needs to
-             * be calculated here based off the on-chip segment size and the
-             * software segment size assumed (4K) */
-            /* TBD */
-            flash_linear_address = segment * sector_size + j * seg_size;
-            flash_linear_address &= ICH8_FLASH_LINEAR_ADDR_MASK;
+             * be calculated here based off the on-chip erase sector size and
+             * the software bank size (4, 8 or 64 KBytes) */
+            flash_linear_address = bank * bank_size + j * sub_sector_size;
             flash_linear_address += hw->flash_base_addr;
+            flash_linear_address &= ICH8_FLASH_LINEAR_ADDR_MASK;
 
             E1000_WRITE_ICH8_REG(hw, ICH8_FLASH_FADDR, flash_linear_address);
 
-            error = e1000_ich8_flash_cycle(hw, 1000000);
+            error = e1000_ich8_flash_cycle(hw, ICH8_FLASH_ERASE_TIMEOUT);
             /* Check if FCERR is set to 1.  If 1, clear it and try the whole
              * sequence a few more times else Done */
             if (error == E1000_SUCCESS) {
@@ -8999,44 +8921,6 @@ e1000_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t segment)
     return error;
 }
 
-/******************************************************************************
- *
- * Reverse duplex setting without breaking the link.
- *
- * hw: Struct containing variables accessed by shared code
- *
- *****************************************************************************/
-#if 0
-int32_t
-e1000_duplex_reversal(struct e1000_hw *hw)
-{
-    int32_t ret_val;
-    uint16_t phy_data;
-
-    if (hw->phy_type != e1000_phy_igp_3)
-        return E1000_SUCCESS;
-
-    ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
-    if (ret_val)
-        return ret_val;
-
-    phy_data ^= MII_CR_FULL_DUPLEX;
-
-    ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
-    if (ret_val)
-        return ret_val;
-
-    ret_val = e1000_read_phy_reg(hw, IGP3E1000_PHY_MISC_CTRL, &phy_data);
-    if (ret_val)
-        return ret_val;
-
-    phy_data |= IGP3_PHY_MISC_DUPLEX_MANUAL_SET;
-    ret_val = e1000_write_phy_reg(hw, IGP3E1000_PHY_MISC_CTRL, phy_data);
-
-    return ret_val;
-}
-#endif  /*  0  */
-
 static int32_t
 e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw,
                                       uint32_t cnf_base_addr, uint32_t cnf_size)
@@ -9071,6 +8955,14 @@ e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw,
 }
 
 
+/******************************************************************************
+ * This function initializes the PHY from the NVM on ICH8 platforms. This
+ * is needed due to an issue where the NVM configuration is not properly
+ * autoloaded after power transitions. Therefore, after each PHY reset, we
+ * will load the configuration data out of the NVM manually.
+ *
+ * hw: Struct containing variables accessed by shared code
+ *****************************************************************************/
 static int32_t
 e1000_init_lcd_from_nvm(struct e1000_hw *hw)
 {
index 4020acb5500580d6e4a356f788ddbcdb40243b11..112447fd8bf2d558f66a6de96559e2b9cac15db3 100644 (file)
@@ -1,25 +1,24 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  any later version.
-  
-  This program is distributed in the hope that it will be useful, but WITHOUT 
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+  Intel PRO/1000 Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.
-  
+
   You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59 
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
@@ -93,11 +92,11 @@ typedef enum {
 
 /* Flow Control Settings */
 typedef enum {
-    e1000_fc_none = 0,
-    e1000_fc_rx_pause = 1,
-    e1000_fc_tx_pause = 2,
-    e1000_fc_full = 3,
-    e1000_fc_default = 0xFF
+    E1000_FC_NONE = 0,
+    E1000_FC_RX_PAUSE = 1,
+    E1000_FC_TX_PAUSE = 2,
+    E1000_FC_FULL = 3,
+    E1000_FC_DEFAULT = 0xFF
 } e1000_fc_type;
 
 struct e1000_shadow_ram {
@@ -302,6 +301,9 @@ typedef enum {
 #define E1000_BLK_PHY_RESET   12
 #define E1000_ERR_SWFW_SYNC 13
 
+#define E1000_BYTE_SWAP_WORD(_value) ((((_value) & 0x00ff) << 8) | \
+                                     (((_value) & 0xff00) >> 8))
+
 /* Function prototypes */
 /* Initialization */
 int32_t e1000_reset_hw(struct e1000_hw *hw);
@@ -314,7 +316,7 @@ int32_t e1000_setup_link(struct e1000_hw *hw);
 int32_t e1000_phy_setup_autoneg(struct e1000_hw *hw);
 void e1000_config_collision_dist(struct e1000_hw *hw);
 int32_t e1000_check_for_link(struct e1000_hw *hw);
-int32_t e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed, uint16_t * duplex);
+int32_t e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t *speed, uint16_t *duplex);
 int32_t e1000_force_mac_fc(struct e1000_hw *hw);
 
 /* PHY */
@@ -322,9 +324,9 @@ int32_t e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *phy
 int32_t e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data);
 int32_t e1000_phy_hw_reset(struct e1000_hw *hw);
 int32_t e1000_phy_reset(struct e1000_hw *hw);
-void e1000_phy_powerdown_workaround(struct e1000_hw *hw);
 int32_t e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
 int32_t e1000_validate_mdi_setting(struct e1000_hw *hw);
+void e1000_phy_powerdown_workaround(struct e1000_hw *hw);
 
 /* EEPROM Functions */
 int32_t e1000_init_eeprom_params(struct e1000_hw *hw);
@@ -393,7 +395,6 @@ int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t words, uin
 int32_t e1000_validate_eeprom_checksum(struct e1000_hw *hw);
 int32_t e1000_update_eeprom_checksum(struct e1000_hw *hw);
 int32_t e1000_write_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t words, uint16_t *data);
-int32_t e1000_read_part_num(struct e1000_hw *hw, uint32_t * part_num);
 int32_t e1000_read_mac_addr(struct e1000_hw * hw);
 
 /* Filters (multicast, vlan, receive) */
@@ -420,6 +421,7 @@ void e1000_pci_set_mwi(struct e1000_hw *hw);
 void e1000_pci_clear_mwi(struct e1000_hw *hw);
 void e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
 void e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
+int32_t e1000_read_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value);
 /* Port I/O is only supported on 82544 and newer */
 void e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value);
 int32_t e1000_disable_pciex_master(struct e1000_hw *hw);
@@ -574,10 +576,10 @@ int32_t e1000_check_phy_reset_block(struct e1000_hw *hw);
  * E1000_RAR_ENTRIES - 1 multicast addresses.
  */
 #define E1000_RAR_ENTRIES 15
-#define E1000_RAR_ENTRIES_ICH8LAN  7
+#define E1000_RAR_ENTRIES_ICH8LAN  6
 
-#define MIN_NUMBER_OF_DESCRIPTORS 8
-#define MAX_NUMBER_OF_DESCRIPTORS 0xFFF8
+#define MIN_NUMBER_OF_DESCRIPTORS  8
+#define MAX_NUMBER_OF_DESCRIPTORS  0xFFF8
 
 /* Receive Descriptor */
 struct e1000_rx_desc {
@@ -1300,6 +1302,7 @@ struct e1000_hw_stats {
     uint64_t algnerrc;
     uint64_t symerrs;
     uint64_t rxerrc;
+    uint64_t txerrc;
     uint64_t mpc;
     uint64_t scc;
     uint64_t ecol;
@@ -1332,8 +1335,9 @@ struct e1000_hw_stats {
     uint64_t gotch;
     uint64_t rnbc;
     uint64_t ruc;
-    uint64_t rfc;
     uint64_t roc;
+    uint64_t rlerrc;
+    uint64_t rfc;
     uint64_t rjc;
     uint64_t mgprc;
     uint64_t mgpdc;
@@ -1440,6 +1444,7 @@ struct e1000_hw {
     boolean_t tbi_compatibility_on;
     boolean_t laa_is_present;
     boolean_t phy_reset_disable;
+    boolean_t initialize_hw_bits_disable;
     boolean_t fc_send_xon;
     boolean_t fc_strict_ieee;
     boolean_t report_tx_early;
@@ -1613,16 +1618,17 @@ struct e1000_hw {
 #define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
 #define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000
 #define E1000_CTRL_EXT_LINK_MODE_TBI  0x00C00000
-#define E1000_CTRL_EXT_LINK_MODE_KMRN    0x00000000
+#define E1000_CTRL_EXT_LINK_MODE_KMRN 0x00000000
 #define E1000_CTRL_EXT_LINK_MODE_SERDES  0x00C00000
+#define E1000_CTRL_EXT_LINK_MODE_SGMII   0x00800000
 #define E1000_CTRL_EXT_WR_WMARK_MASK  0x03000000
 #define E1000_CTRL_EXT_WR_WMARK_256   0x00000000
 #define E1000_CTRL_EXT_WR_WMARK_320   0x01000000
 #define E1000_CTRL_EXT_WR_WMARK_384   0x02000000
 #define E1000_CTRL_EXT_WR_WMARK_448   0x03000000
-#define E1000_CTRL_EXT_DRV_LOAD       0x10000000  /* Driver loaded bit for FW */
-#define E1000_CTRL_EXT_IAME           0x08000000  /* Interrupt acknowledge Auto-mask */
-#define E1000_CTRL_EXT_INT_TIMER_CLR  0x20000000  /* Clear Interrupt timers after IMS clear */
+#define E1000_CTRL_EXT_DRV_LOAD       0x10000000 /* Driver loaded bit for FW */
+#define E1000_CTRL_EXT_IAME           0x08000000 /* Interrupt acknowledge Auto-mask */
+#define E1000_CTRL_EXT_INT_TIMER_CLR  0x20000000 /* Clear Interrupt timers after IMS clear */
 #define E1000_CRTL_EXT_PB_PAREN       0x01000000 /* packet buffer parity error detection enabled */
 #define E1000_CTRL_EXT_DF_PAREN       0x02000000 /* descriptor FIFO parity error detection enable */
 #define E1000_CTRL_EXT_GHOST_PAREN    0x40000000
@@ -2218,6 +2224,11 @@ struct e1000_host_command_info {
 #define E1000_FACTPS_LAN_FUNC_SEL                   0x40000000
 #define E1000_FACTPS_PM_STATE_CHANGED               0x80000000
 
+/* PCI-Ex Config Space */
+#define PCI_EX_LINK_STATUS           0x12
+#define PCI_EX_LINK_WIDTH_MASK       0x3F0
+#define PCI_EX_LINK_WIDTH_SHIFT      4
+
 /* EEPROM Commands - Microwire */
 #define EEPROM_READ_OPCODE_MICROWIRE  0x6  /* EEPROM read opcode */
 #define EEPROM_WRITE_OPCODE_MICROWIRE 0x5  /* EEPROM write opcode */
@@ -3120,6 +3131,7 @@ struct e1000_host_command_info {
 /* I = Integrated
  * E = External
  */
+#define M88_VENDOR         0x0141
 #define M88E1000_E_PHY_ID  0x01410C50
 #define M88E1000_I_PHY_ID  0x01410C30
 #define M88E1011_I_PHY_ID  0x01410C20
@@ -3244,10 +3256,12 @@ struct e1000_host_command_info {
 #define IFE_PSCL_PROBE_LEDS_OFF              0x0006  /* Force LEDs 0 and 2 off */
 #define IFE_PSCL_PROBE_LEDS_ON               0x0007  /* Force LEDs 0 and 2 on */
 
-#define ICH8_FLASH_COMMAND_TIMEOUT           500   /* 500 ms , should be adjusted */
-#define ICH8_FLASH_CYCLE_REPEAT_COUNT        10    /* 10 cycles , should be adjusted */
+#define ICH8_FLASH_COMMAND_TIMEOUT           5000    /* 5000 uSecs - adjusted */
+#define ICH8_FLASH_ERASE_TIMEOUT             3000000 /* Up to 3 seconds - worst case */
+#define ICH8_FLASH_CYCLE_REPEAT_COUNT        10      /* 10 cycles */
 #define ICH8_FLASH_SEG_SIZE_256              256
 #define ICH8_FLASH_SEG_SIZE_4K               4096
+#define ICH9_FLASH_SEG_SIZE_8K               8192
 #define ICH8_FLASH_SEG_SIZE_64K              65536
 
 #define ICH8_CYCLE_READ                      0x0
index 3f6a752700a101a93ee18fef71518492a1e233ed..7dca38fba6a1809605340915aa7c9d65abeaa206 100644 (file)
@@ -1,25 +1,24 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  any later version.
-  
-  This program is distributed in the hope that it will be useful, but WITHOUT 
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+  Intel PRO/1000 Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.
-  
+
   You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59 
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
@@ -36,7 +35,7 @@ static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
 #else
 #define DRIVERNAPI "-NAPI"
 #endif
-#define DRV_VERSION "7.2.7-k2"DRIVERNAPI
+#define DRV_VERSION "7.2.9-k2"DRIVERNAPI
 char e1000_driver_version[] = DRV_VERSION;
 static char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
 
@@ -110,16 +109,24 @@ static struct pci_device_id e1000_pci_tbl[] = {
 
 MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
 
+int e1000_up(struct e1000_adapter *adapter);
+void e1000_down(struct e1000_adapter *adapter);
+void e1000_reinit_locked(struct e1000_adapter *adapter);
+void e1000_reset(struct e1000_adapter *adapter);
+int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
+int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
+int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
+void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
+void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
 static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
-                                    struct e1000_tx_ring *txdr);
+                             struct e1000_tx_ring *txdr);
 static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
-                                    struct e1000_rx_ring *rxdr);
+                             struct e1000_rx_ring *rxdr);
 static void e1000_free_tx_resources(struct e1000_adapter *adapter,
-                                    struct e1000_tx_ring *tx_ring);
+                             struct e1000_tx_ring *tx_ring);
 static void e1000_free_rx_resources(struct e1000_adapter *adapter,
-                                    struct e1000_rx_ring *rx_ring);
-
-/* Local Function Prototypes */
+                             struct e1000_rx_ring *rx_ring);
+void e1000_update_stats(struct e1000_adapter *adapter);
 
 static int e1000_init_module(void);
 static void e1000_exit_module(void);
@@ -172,6 +179,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
 static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
 static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
                           int cmd);
+void e1000_set_ethtool_ops(struct net_device *netdev);
 static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
 static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
 static void e1000_tx_timeout(struct net_device *dev);
@@ -196,6 +204,8 @@ static void e1000_shutdown(struct pci_dev *pdev);
 static void e1000_netpoll (struct net_device *netdev);
 #endif
 
+extern void e1000_check_options(struct e1000_adapter *adapter);
+
 static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
                      pci_channel_state_t state);
 static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
@@ -212,9 +222,9 @@ static struct pci_driver e1000_driver = {
        .id_table = e1000_pci_tbl,
        .probe    = e1000_probe,
        .remove   = __devexit_p(e1000_remove),
+#ifdef CONFIG_PM
        /* Power Managment Hooks */
        .suspend  = e1000_suspend,
-#ifdef CONFIG_PM
        .resume   = e1000_resume,
 #endif
        .shutdown = e1000_shutdown,
@@ -466,13 +476,14 @@ e1000_up(struct e1000_adapter *adapter)
 
        adapter->tx_queue_len = netdev->tx_queue_len;
 
-       mod_timer(&adapter->watchdog_timer, jiffies);
-
 #ifdef CONFIG_E1000_NAPI
        netif_poll_enable(netdev);
 #endif
        e1000_irq_enable(adapter);
 
+       clear_bit(__E1000_DOWN, &adapter->flags);
+
+       mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
        return 0;
 }
 
@@ -502,25 +513,48 @@ void e1000_power_up_phy(struct e1000_adapter *adapter)
 
 static void e1000_power_down_phy(struct e1000_adapter *adapter)
 {
-       boolean_t mng_mode_enabled = (adapter->hw.mac_type >= e1000_82571) &&
-                                     e1000_check_mng_mode(&adapter->hw);
-       /* Power down the PHY so no link is implied when interface is down
-        * The PHY cannot be powered down if any of the following is TRUE
+       /* Power down the PHY so no link is implied when interface is down *
+        * The PHY cannot be powered down if any of the following is TRUE *
         * (a) WoL is enabled
         * (b) AMT is active
         * (c) SoL/IDER session is active */
        if (!adapter->wol && adapter->hw.mac_type >= e1000_82540 &&
-           adapter->hw.mac_type != e1000_ich8lan &&
-           adapter->hw.media_type == e1000_media_type_copper &&
-           !(E1000_READ_REG(&adapter->hw, MANC) & E1000_MANC_SMBUS_EN) &&
-           !mng_mode_enabled &&
-           !e1000_check_phy_reset_block(&adapter->hw)) {
+          adapter->hw.media_type == e1000_media_type_copper) {
                uint16_t mii_reg = 0;
+
+               switch (adapter->hw.mac_type) {
+               case e1000_82540:
+               case e1000_82545:
+               case e1000_82545_rev_3:
+               case e1000_82546:
+               case e1000_82546_rev_3:
+               case e1000_82541:
+               case e1000_82541_rev_2:
+               case e1000_82547:
+               case e1000_82547_rev_2:
+                       if (E1000_READ_REG(&adapter->hw, MANC) &
+                           E1000_MANC_SMBUS_EN)
+                               goto out;
+                       break;
+               case e1000_82571:
+               case e1000_82572:
+               case e1000_82573:
+               case e1000_80003es2lan:
+               case e1000_ich8lan:
+                       if (e1000_check_mng_mode(&adapter->hw) ||
+                           e1000_check_phy_reset_block(&adapter->hw))
+                               goto out;
+                       break;
+               default:
+                       goto out;
+               }
                e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
                mii_reg |= MII_CR_POWER_DOWN;
                e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
                mdelay(1);
        }
+out:
+       return;
 }
 
 void
@@ -528,6 +562,10 @@ e1000_down(struct e1000_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
 
+       /* signal that we're down so the interrupt handler does not
+        * reschedule our watchdog timer */
+       set_bit(__E1000_DOWN, &adapter->flags);
+
        e1000_irq_disable(adapter);
 
        del_timer_sync(&adapter->tx_fifo_stall_timer);
@@ -563,6 +601,9 @@ void
 e1000_reset(struct e1000_adapter *adapter)
 {
        uint32_t pba, manc;
+#ifdef DISABLE_MULR
+       uint32_t tctl;
+#endif
        uint16_t fc_high_water_mark = E1000_FC_HIGH_DIFF;
 
        /* Repartition Pba for greater than 9k mtu
@@ -629,6 +670,12 @@ e1000_reset(struct e1000_adapter *adapter)
        e1000_reset_hw(&adapter->hw);
        if (adapter->hw.mac_type >= e1000_82544)
                E1000_WRITE_REG(&adapter->hw, WUC, 0);
+#ifdef DISABLE_MULR
+       /* disable Multiple Reads in Transmit Control Register for debugging */
+       tctl = E1000_READ_REG(hw, TCTL);
+       E1000_WRITE_REG(hw, TCTL, tctl & ~E1000_TCTL_MULR);
+
+#endif
        if (e1000_init_hw(&adapter->hw))
                DPRINTK(PROBE, ERR, "Hardware Error\n");
        e1000_update_mng_vlan(adapter);
@@ -652,9 +699,7 @@ e1000_reset(struct e1000_adapter *adapter)
                                    phy_data);
        }
 
-       if (adapter->hw.mac_type < e1000_ich8lan)
-       /* FIXME: this code is duplicate and wrong for PCI Express */
-       if (adapter->en_mng_pt) {
+       if ((adapter->en_mng_pt) && (adapter->hw.mac_type < e1000_82571)) {
                manc = E1000_READ_REG(&adapter->hw, MANC);
                manc |= (E1000_MANC_ARP_EN | E1000_MANC_EN_MNG2HOST);
                E1000_WRITE_REG(&adapter->hw, MANC, manc);
@@ -760,7 +805,7 @@ e1000_probe(struct pci_dev *pdev,
 #ifdef CONFIG_NET_POLL_CONTROLLER
        netdev->poll_controller = e1000_netpoll;
 #endif
-       strcpy(netdev->name, pci_name(pdev));
+       strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
 
        netdev->mem_start = mmio_start;
        netdev->mem_end = mmio_start + mmio_len;
@@ -863,11 +908,6 @@ e1000_probe(struct pci_dev *pdev,
        INIT_WORK(&adapter->reset_task,
                (void (*)(void *))e1000_reset_task, netdev);
 
-       /* we're going to reset, so assume we have no link for now */
-
-       netif_carrier_off(netdev);
-       netif_stop_queue(netdev);
-
        e1000_check_options(adapter);
 
        /* Initial Wake on LAN setting
@@ -974,6 +1014,10 @@ e1000_probe(struct pci_dev *pdev,
        if ((err = register_netdev(netdev)))
                goto err_register;
 
+       /* tell the stack to leave us alone until e1000_open() is called */
+       netif_carrier_off(netdev);
+       netif_stop_queue(netdev);
+
        DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
 
        cards_found++;
@@ -1032,8 +1076,7 @@ e1000_remove(struct pci_dev *pdev)
 
        flush_scheduled_work();
 
-       if (adapter->hw.mac_type >= e1000_82540 &&
-          adapter->hw.mac_type != e1000_ich8lan &&
+       if (adapter->hw.mac_type < e1000_82571 &&
           adapter->hw.media_type == e1000_media_type_copper) {
                manc = E1000_READ_REG(&adapter->hw, MANC);
                if (manc & E1000_MANC_SMBUS_EN) {
@@ -1161,6 +1204,8 @@ e1000_sw_init(struct e1000_adapter *adapter)
        atomic_set(&adapter->irq_sem, 1);
        spin_lock_init(&adapter->stats_lock);
 
+       set_bit(__E1000_DOWN, &adapter->flags);
+
        return 0;
 }
 
@@ -1226,7 +1271,7 @@ e1000_open(struct net_device *netdev)
        int err;
 
        /* disallow open during test */
-       if (test_bit(__E1000_DRIVER_TESTING, &adapter->flags))
+       if (test_bit(__E1000_TESTING, &adapter->flags))
                return -EBUSY;
 
        /* allocate transmit descriptors */
@@ -1299,8 +1344,12 @@ e1000_close(struct net_device *netdev)
        e1000_free_all_tx_resources(adapter);
        e1000_free_all_rx_resources(adapter);
 
+       /* kill manageability vlan ID if supported, but not if a vlan with
+        * the same ID is registered on the host OS (let 8021q kill it) */
        if ((adapter->hw.mng_cookie.status &
-                         E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
+                         E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
+            !(adapter->vlgrp &&
+                         adapter->vlgrp->vlan_devices[adapter->mng_vlan_id])) {
                e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
        }
 
@@ -1510,27 +1559,14 @@ e1000_configure_tx(struct e1000_adapter *adapter)
        /* Program the Transmit Control Register */
 
        tctl = E1000_READ_REG(hw, TCTL);
-
        tctl &= ~E1000_TCTL_CT;
        tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
                (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
 
-#ifdef DISABLE_MULR
-       /* disable Multiple Reads for debugging */
-       tctl &= ~E1000_TCTL_MULR;
-#endif
-
        if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572) {
                tarc = E1000_READ_REG(hw, TARC0);
-               tarc |= ((1 << 25) | (1 << 21));
+               tarc |= (1 << 21);
                E1000_WRITE_REG(hw, TARC0, tarc);
-               tarc = E1000_READ_REG(hw, TARC1);
-               tarc |= (1 << 25);
-               if (tctl & E1000_TCTL_MULR)
-                       tarc &= ~(1 << 28);
-               else
-                       tarc |= (1 << 28);
-               E1000_WRITE_REG(hw, TARC1, tarc);
        } else if (hw->mac_type == e1000_80003es2lan) {
                tarc = E1000_READ_REG(hw, TARC0);
                tarc |= 1;
@@ -2892,6 +2928,35 @@ e1000_transfer_dhcp_info(struct e1000_adapter *adapter, struct sk_buff *skb)
        return 0;
 }
 
+static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
+{
+       struct e1000_adapter *adapter = netdev_priv(netdev);
+       struct e1000_tx_ring *tx_ring = adapter->tx_ring;
+
+       netif_stop_queue(netdev);
+       /* Herbert's original patch had:
+        *  smp_mb__after_netif_stop_queue();
+        * but since that doesn't exist yet, just open code it. */
+       smp_mb();
+
+       /* We need to check again in a case another CPU has just
+        * made room available. */
+       if (likely(E1000_DESC_UNUSED(tx_ring) < size))
+               return -EBUSY;
+
+       /* A reprieve! */
+       netif_start_queue(netdev);
+       return 0;
+}
+
+static int e1000_maybe_stop_tx(struct net_device *netdev,
+                               struct e1000_tx_ring *tx_ring, int size)
+{
+       if (likely(E1000_DESC_UNUSED(tx_ring) >= size))
+               return 0;
+       return __e1000_maybe_stop_tx(netdev, size);
+}
+
 #define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
 static int
 e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
@@ -2910,6 +2975,10 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        unsigned int f;
        len -= skb->data_len;
 
+       /* This goes back to the question of how to logically map a tx queue
+        * to a flow.  Right now, performance is impacted slightly negatively
+        * if using multiple tx queues.  If the stack breaks away from a
+        * single qdisc implementation, we can look at this again. */
        tx_ring = adapter->tx_ring;
 
        if (unlikely(skb->len <= 0)) {
@@ -3005,8 +3074,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 
        /* need: count + 2 desc gap to keep tail from touching
         * head, otherwise try next time */
-       if (unlikely(E1000_DESC_UNUSED(tx_ring) < count + 2)) {
-               netif_stop_queue(netdev);
+       if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2))) {
                spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
                return NETDEV_TX_BUSY;
        }
@@ -3014,7 +3082,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        if (unlikely(adapter->hw.mac_type == e1000_82547)) {
                if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
                        netif_stop_queue(netdev);
-                       mod_timer(&adapter->tx_fifo_stall_timer, jiffies);
+                       mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
                        spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
                        return NETDEV_TX_BUSY;
                }
@@ -3053,8 +3121,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        netdev->trans_start = jiffies;
 
        /* Make sure there is space in the ring for the next send. */
-       if (unlikely(E1000_DESC_UNUSED(tx_ring) < MAX_SKB_FRAGS + 2))
-               netif_stop_queue(netdev);
+       e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
 
        spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
        return NETDEV_TX_OK;
@@ -3131,11 +3198,13 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu)
                }
                break;
        case e1000_82573:
-               /* only enable jumbo frames if ASPM is disabled completely
-                * this means both bits must be zero in 0x1A bits 3:2 */
+               /* Jumbo Frames not supported if:
+                * - this is not an 82573L device
+                * - ASPM is enabled in any way (0x1A bits 3:2) */
                e1000_read_eeprom(&adapter->hw, EEPROM_INIT_3GIO_3, 1,
                                  &eeprom_data);
-               if (eeprom_data & EEPROM_WORD1A_ASPM_MASK) {
+               if ((adapter->hw.device_id != E1000_DEV_ID_82573L) ||
+                   (eeprom_data & EEPROM_WORD1A_ASPM_MASK)) {
                        if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
                                DPRINTK(PROBE, ERR,
                                        "Jumbo Frames not supported.\n");
@@ -3143,6 +3212,8 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu)
                        }
                        break;
                }
+               /* ERT will be enabled later to enable wire speed receives */
+
                /* fall through to get support */
        case e1000_82571:
        case e1000_82572:
@@ -3328,16 +3399,15 @@ e1000_update_stats(struct e1000_adapter *adapter)
                adapter->stats.crcerrs + adapter->stats.algnerrc +
                adapter->stats.ruc + adapter->stats.roc +
                adapter->stats.cexterr;
-       adapter->net_stats.rx_length_errors = adapter->stats.ruc +
-                                             adapter->stats.roc;
+       adapter->stats.rlerrc = adapter->stats.ruc + adapter->stats.roc;
+       adapter->net_stats.rx_length_errors = adapter->stats.rlerrc;
        adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
        adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
        adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
 
        /* Tx Errors */
-
-       adapter->net_stats.tx_errors = adapter->stats.ecol +
-                                      adapter->stats.latecol;
+       adapter->stats.txerrc = adapter->stats.ecol + adapter->stats.latecol;
+       adapter->net_stats.tx_errors = adapter->stats.txerrc;
        adapter->net_stats.tx_aborted_errors = adapter->stats.ecol;
        adapter->net_stats.tx_window_errors = adapter->stats.latecol;
        adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs;
@@ -3408,7 +3478,9 @@ e1000_intr(int irq, void *data, struct pt_regs *regs)
                        rctl = E1000_READ_REG(hw, RCTL);
                        E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
                }
-               mod_timer(&adapter->watchdog_timer, jiffies);
+               /* guard against interrupt when we're going down */
+               if (!test_bit(__E1000_DOWN, &adapter->flags))
+                       mod_timer(&adapter->watchdog_timer, jiffies + 1);
        }
 
 #ifdef CONFIG_E1000_NAPI
@@ -3546,13 +3618,14 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
        tx_ring->next_to_clean = i;
 
 #define TX_WAKE_THRESHOLD 32
-       if (unlikely(cleaned && netif_queue_stopped(netdev) &&
-                    netif_carrier_ok(netdev))) {
-               spin_lock(&tx_ring->tx_lock);
-               if (netif_queue_stopped(netdev) &&
-                   (E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD))
+       if (unlikely(cleaned && netif_carrier_ok(netdev) &&
+                    E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
+               /* Make sure that anybody stopping the queue after this
+                * sees the new next_to_clean.
+                */
+               smp_mb();
+               if (netif_queue_stopped(netdev))
                        netif_wake_queue(netdev);
-               spin_unlock(&tx_ring->tx_lock);
        }
 
        if (adapter->detect_tx_hung) {
@@ -4412,13 +4485,21 @@ e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
        pci_write_config_word(adapter->pdev, reg, *value);
 }
 
-#if 0
-uint32_t
-e1000_io_read(struct e1000_hw *hw, unsigned long port)
+int32_t
+e1000_read_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
 {
-       return inl(port);
+    struct e1000_adapter *adapter = hw->back;
+    uint16_t cap_offset;
+
+    cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
+    if (!cap_offset)
+        return -E1000_ERR_CONFIG;
+
+    pci_read_config_word(adapter->pdev, cap_offset + reg, value);
+
+    return E1000_SUCCESS;
 }
-#endif  /*  0  */
+
 
 void
 e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value)
@@ -4693,9 +4774,7 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
                pci_enable_wake(pdev, PCI_D3cold, 0);
        }
 
-       /* FIXME: this code is incorrect for PCI Express */
-       if (adapter->hw.mac_type >= e1000_82540 &&
-          adapter->hw.mac_type != e1000_ich8lan &&
+       if (adapter->hw.mac_type < e1000_82571 &&
           adapter->hw.media_type == e1000_media_type_copper) {
                manc = E1000_READ_REG(&adapter->hw, MANC);
                if (manc & E1000_MANC_SMBUS_EN) {
@@ -4747,9 +4826,7 @@ e1000_resume(struct pci_dev *pdev)
 
        netif_device_attach(netdev);
 
-       /* FIXME: this code is incorrect for PCI Express */
-       if (adapter->hw.mac_type >= e1000_82540 &&
-          adapter->hw.mac_type != e1000_ich8lan &&
+       if (adapter->hw.mac_type < e1000_82571 &&
           adapter->hw.media_type == e1000_media_type_copper) {
                manc = E1000_READ_REG(&adapter->hw, MANC);
                manc &= ~(E1000_MANC_ARP_EN);
@@ -4835,8 +4912,8 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
        }
        pci_set_master(pdev);
 
-       pci_enable_wake(pdev, 3, 0);
-       pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */
+       pci_enable_wake(pdev, PCI_D3hot, 0);
+       pci_enable_wake(pdev, PCI_D3cold, 0);
 
        /* Perform card reset only on one instance of the card */
        if (PCI_FUNC (pdev->devfn) != 0)
index 46bc49df15e78e896a532666aa3aa6604c6a84d2..a464cb290621537737074c8393d5eea38d1e9a23 100644 (file)
@@ -1,25 +1,24 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  any later version.
-  
-  This program is distributed in the hope that it will be useful, but WITHOUT 
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+  Intel PRO/1000 Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.
-  
+
   You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59 
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
index 2128427389724c4bca3c4ca6181bca2d86a9b41e..9c3c1acefccc3c92eefcc19667bf445eeb11a889 100644 (file)
@@ -1,25 +1,24 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  any later version.
-  
-  This program is distributed in the hope that it will be useful, but WITHOUT 
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+  Intel PRO/1000 Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.
-  
+
   You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59 
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
@@ -397,17 +396,17 @@ e1000_check_options(struct e1000_adapter *adapter)
        { /* Flow Control */
 
                struct e1000_opt_list fc_list[] =
-                       {{ e1000_fc_none,    "Flow Control Disabled" },
-                        { e1000_fc_rx_pause,"Flow Control Receive Only" },
-                        { e1000_fc_tx_pause,"Flow Control Transmit Only" },
-                        { e1000_fc_full,    "Flow Control Enabled" },
-                        { e1000_fc_default, "Flow Control Hardware Default" }};
+                       {{ E1000_FC_NONE,    "Flow Control Disabled" },
+                        { E1000_FC_RX_PAUSE,"Flow Control Receive Only" },
+                        { E1000_FC_TX_PAUSE,"Flow Control Transmit Only" },
+                        { E1000_FC_FULL,    "Flow Control Enabled" },
+                        { E1000_FC_DEFAULT, "Flow Control Hardware Default" }};
 
                struct e1000_option opt = {
                        .type = list_option,
                        .name = "Flow Control",
                        .err  = "reading default settings from EEPROM",
-                       .def  = e1000_fc_default,
+                       .def  = E1000_FC_DEFAULT,
                        .arg  = { .l = { .nr = ARRAY_SIZE(fc_list),
                                         .p = fc_list }}
                };
index 34412bc7c4b638a1c5458c3edb220780adeb053c..d01870619a4aefc7ca9d278b58250da77fa3f809 100644 (file)
@@ -944,12 +944,13 @@ extern int fs_mii_connect(struct net_device *dev);
 extern void fs_mii_disconnect(struct net_device *dev);
 
 static struct net_device *fs_init_instance(struct device *dev,
-               const struct fs_platform_info *fpi)
+               struct fs_platform_info *fpi)
 {
        struct net_device *ndev = NULL;
        struct fs_enet_private *fep = NULL;
        int privsize, i, r, err = 0, registered = 0;
 
+       fpi->fs_no = fs_get_id(fpi);
        /* guard */
        if ((unsigned int)fpi->fs_no >= FS_MAX_INDEX)
                return ERR_PTR(-EINVAL);
@@ -971,7 +972,7 @@ static struct net_device *fs_init_instance(struct device *dev,
        dev_set_drvdata(dev, ndev);
        fep->fpi = fpi;
        if (fpi->init_ioports)
-               fpi->init_ioports();
+               fpi->init_ioports((struct fs_platform_info *)fpi);
 
 #ifdef CONFIG_FS_ENET_HAS_FEC
        if (fs_get_fec_index(fpi->fs_no) >= 0)
index 03b3df33d81b1c6c325613a881d9aad1d0d486ce..ae8ad4f763bff9fa1e5634c7422d6aef1fd87ae3 100644 (file)
@@ -188,10 +188,12 @@ struct hp100_private {
 /*
  *  variables
  */
+#ifdef CONFIG_ISA
 static const char *hp100_isa_tbl[] = {
        "HWPF150", /* HP J2573 rev A */
        "HWP1950", /* HP J2573 */
 };
+#endif
 
 #ifdef CONFIG_EISA
 static struct eisa_device_id hp100_eisa_tbl[] = {
@@ -333,6 +335,7 @@ static __devinit const char *hp100_read_id(int ioaddr)
        return str;
 }
 
+#ifdef CONFIG_ISA
 static __init int hp100_isa_probe1(struct net_device *dev, int ioaddr)
 {
        const char *sig;
@@ -390,9 +393,9 @@ static int  __init hp100_isa_probe(struct net_device *dev, int addr)
        }
        return err;
 }
+#endif /* CONFIG_ISA */
 
-
-#ifndef MODULE
+#if !defined(MODULE) && defined(CONFIG_ISA)
 struct net_device * __init hp100_probe(int unit)
 {
        struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private));
@@ -422,7 +425,7 @@ struct net_device * __init hp100_probe(int unit)
        free_netdev(dev);
        return ERR_PTR(err);
 }
-#endif
+#endif /* !MODULE && CONFIG_ISA */
 
 static int __devinit hp100_probe1(struct net_device *dev, int ioaddr,
                                  u_char bus, struct pci_dev *pci_dev)
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 6469130c1413f532633e0a87df31c821a1ae36c2..c26a4b8e552a52274832b551a45c2d47ca357da7 100644 (file)
@@ -200,8 +200,8 @@ static struct net_device_stats *ifb_get_stats(struct net_device *dev)
 
        pr_debug("tasklets stats %ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld \n",
                dp->st_task_enter, dp->st_txq_refl_try, dp->st_rxq_enter,
-               dp->st_rx2tx_tran dp->st_rxq_notenter, dp->st_rx_frm_egr,
-               dp->st_rx_frm_ing, dp->st_rxq_check, dp->st_rxq_rsch );
+               dp->st_rx2tx_tran, dp->st_rxq_notenter, dp->st_rx_frm_egr,
+               dp->st_rx_frm_ing, dp->st_rxq_check, dp->st_rxq_rsch);
 
        return stats;
 }
index a8a2d3d03567fc9f082a64533df578e1c077d09c..838a5084fa00c93f1f46e3ec890e9ef2cc6fba07 100644 (file)
@@ -1,33 +1,33 @@
 ################################################################################
 #
-# 
-# Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-# 
-# This program is free software; you can redistribute it and/or modify it 
-# under the terms of the GNU General Public License as published by the Free 
-# Software Foundation; either version 2 of the License, or (at your option) 
-# any later version.
-# 
-# This program is distributed in the hope that it will be useful, but WITHOUT 
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+# Intel PRO/10GbE Linux driver
+# Copyright(c) 1999 - 2006 Intel Corporation.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 # more details.
-# 
+#
 # You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 59 
-# Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-# 
-# The full GNU General Public License is included in this distribution in the
-# file called LICENSE.
-# 
+# this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# The full GNU General Public License is included in this distribution in
+# the file called "COPYING".
+#
 # Contact Information:
 # Linux NICS <linux.nics@intel.com>
+# e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
 # Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 #
 ################################################################################
 
 #
-# Makefile for the Intel(R) PRO/10GbE driver
+# Makefile for the Intel(R) PRO/10GbE ethernet driver
 #
 
 obj-$(CONFIG_IXGB) += ixgb.o
index a51604b3651f0063ed3c9362803d688305b1e855..50ffe90488ff4584c033618cb86e2e14859867fc 100644 (file)
@@ -1,27 +1,27 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  any later version.
-  
-  This program is distributed in the hope that it will be useful, but WITHOUT 
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+  Intel PRO/10GbE Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.
-  
+
   You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59 
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 *******************************************************************************/
@@ -111,7 +111,7 @@ struct ixgb_adapter;
 #define IXGB_RXBUFFER_16384 16384
 
 /* How many Rx Buffers do we bundle into one write to the hardware ? */
-#define IXGB_RX_BUFFER_WRITE   4       /* Must be power of 2 */
+#define IXGB_RX_BUFFER_WRITE   8       /* Must be power of 2 */
 
 /* only works for sizes that are powers of 2 */
 #define IXGB_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1)))
index 8357c5590bfb8a4887250958cbb422c1241798dc..f15aebde7b9026bea724f90785e08847889c84f0 100644 (file)
@@ -1,27 +1,27 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  any later version.
-  
-  This program is distributed in the hope that it will be useful, but WITHOUT 
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+  Intel PRO/10GbE Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.
-  
+
   You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59 
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 *******************************************************************************/
index bf6fa220f38e64eabe3c0ae0ce0dce14f54d45d3..ef236b935c15559edb5cd9c69889fd73bef9eb70 100644 (file)
@@ -1,27 +1,27 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  any later version.
-  
-  This program is distributed in the hope that it will be useful, but WITHOUT 
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+  Intel PRO/10GbE Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.
-  
+
   You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59 
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 *******************************************************************************/
index 64a383e4e892a83eb5bc6091bcbb02030b4afd16..cd22523fb03521535b2fd71c074e9984599d9278 100644 (file)
@@ -1,27 +1,27 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  any later version.
-  
-  This program is distributed in the hope that it will be useful, but WITHOUT 
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+  Intel PRO/10GbE Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.
-  
+
   You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59 
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 *******************************************************************************/
index acc6df7a6b38c55c0f168079902d4f290332700d..02089b64e42c55f6672cd178790c7ba6a9bb63f2 100644 (file)
@@ -1,27 +1,27 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  any later version.
-  
-  This program is distributed in the hope that it will be useful, but WITHOUT 
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+  Intel PRO/10GbE Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.
-  
+
   You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59 
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 *******************************************************************************/
index cb4568915ada7a363b3e6d435bc809f15f176aae..40ef5ca88717d4f4d3f9bfa0e5606f3003d06803 100644 (file)
@@ -1,27 +1,27 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  any later version.
-  
-  This program is distributed in the hope that it will be useful, but WITHOUT 
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+  Intel PRO/10GbE Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.
-  
+
   You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59 
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 *******************************************************************************/
index 9fd61189b4b29c73ad71343802fbbce0a4adbecc..4376e7e8fbef275c4b2efe407fcfce9feaf08d17 100644 (file)
@@ -1,27 +1,27 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  any later version.
-  
-  This program is distributed in the hope that it will be useful, but WITHOUT 
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+  Intel PRO/10GbE Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.
-  
+
   You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59 
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 *******************************************************************************/
index 2e0f4b950a902cf9df22d2fcc8acac47b91c6f11..cfde7c2569bb80314d979191fa7afad39f143122 100644 (file)
@@ -1,27 +1,27 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  any later version.
-  
-  This program is distributed in the hope that it will be useful, but WITHOUT 
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+  Intel PRO/10GbE Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.
-  
+
   You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59 
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 *******************************************************************************/
@@ -36,7 +36,7 @@ static char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver";
 #else
 #define DRIVERNAPI "-NAPI"
 #endif
-#define DRV_VERSION            "1.0.112-k2"DRIVERNAPI
+#define DRV_VERSION            "1.0.117-k2"DRIVERNAPI
 char ixgb_driver_version[] = DRV_VERSION;
 static char ixgb_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
 
@@ -437,7 +437,7 @@ ixgb_probe(struct pci_dev *pdev,
        netdev->poll_controller = ixgb_netpoll;
 #endif
 
-       strcpy(netdev->name, pci_name(pdev));
+       strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
        netdev->mem_start = mmio_start;
        netdev->mem_end = mmio_start + mmio_len;
        netdev->base_addr = adapter->hw.io_base;
@@ -2230,7 +2230,7 @@ static pci_ers_result_t ixgb_io_error_detected (struct pci_dev *pdev,
                                     enum pci_channel_state state)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
-       struct ixgb_adapter *adapter = netdev->priv;
+       struct ixgb_adapter *adapter = netdev_priv(netdev);
 
        if(netif_running(netdev))
                ixgb_down(adapter, TRUE);
@@ -2253,7 +2253,7 @@ static pci_ers_result_t ixgb_io_error_detected (struct pci_dev *pdev,
 static pci_ers_result_t ixgb_io_slot_reset (struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
-       struct ixgb_adapter *adapter = netdev->priv;
+       struct ixgb_adapter *adapter = netdev_priv(netdev);
 
        if(pci_enable_device(pdev)) {
                DPRINTK(PROBE, ERR, "Cannot re-enable PCI device after reset.\n");
@@ -2297,7 +2297,7 @@ static pci_ers_result_t ixgb_io_slot_reset (struct pci_dev *pdev)
 static void ixgb_io_resume (struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
-       struct ixgb_adapter *adapter = netdev->priv;
+       struct ixgb_adapter *adapter = netdev_priv(netdev);
 
        pci_set_master(pdev);
 
index 19cb1d586dec6d67659b57a4e5517d9ee210a05a..8434d752fd81873b726e47207544a8dd9647235b 100644 (file)
@@ -1,27 +1,27 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  any later version.
-  
-  This program is distributed in the hope that it will be useful, but WITHOUT 
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+  Intel PRO/10GbE Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.
-  
+
   You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59 
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 *******************************************************************************/
index 39fbed29a3dfd9fc7018db044fa204546b3cb751..b27442a121f2fba05b388d0691c118c4170a0b78 100644 (file)
@@ -1,27 +1,27 @@
 /*******************************************************************************
 
-  
-  Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-  
-  This program is free software; you can redistribute it and/or modify it 
-  under the terms of the GNU General Public License as published by the Free 
-  Software Foundation; either version 2 of the License, or (at your option) 
-  any later version.
-  
-  This program is distributed in the hope that it will be useful, but WITHOUT 
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+  Intel PRO/10GbE Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.
-  
+
   You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc., 59 
-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 *******************************************************************************/
index 19f7ee63276fb56a6ad4f64e0adf3200bf049a59..94b47c8d0ab402c681bb73057adb71952ede69c1 100644 (file)
@@ -289,9 +289,13 @@ static int fixed_mdio_register_device(int number, int speed, int duplex)
                goto probe_fail;
        }
 
-       device_bind_driver(&phydev->dev);
+       err = device_bind_driver(&phydev->dev);
+
        up_write(&phydev->dev.bus->subsys.rwsem);
 
+       if (err)
+               goto probe_fail;
+
        return 0;
 
 probe_fail:
index ecd3da151e2d2a17eca4dabf378a3cef41a341df..3bbd5e70c209100cdf274408200c5ab1b957f9b9 100644 (file)
@@ -212,11 +212,13 @@ struct phy_device *phy_attach(struct net_device *dev,
 
                err = d->driver->probe(d);
 
-               if (err < 0)
-                       return ERR_PTR(err);
+               if (err >= 0)
+                       err = device_bind_driver(d);
 
-               device_bind_driver(d);
                up_write(&d->bus->subsys.rwsem);
+
+               if (err)
+                       return ERR_PTR(err);
        }
 
        if (phydev->attached_dev) {
index 7eeefa2d6c89c8fd1691add25fbbbfde5ea7c2cd..396e7df3c61b8573017d829fe298b7f7b1ba1f9d 100644 (file)
 #include "sky2.h"
 
 #define DRV_NAME               "sky2"
-#define DRV_VERSION            "1.7"
+#define DRV_VERSION            "1.9"
 #define PFX                    DRV_NAME " "
 
 /*
  * The Yukon II chipset takes 64 bit command blocks (called list elements)
  * that are organized into three (receive, transmit, status) different rings
- * similar to Tigon3. A transmit can require several elements;
- * a receive requires one (or two if using 64 bit dma).
+ * similar to Tigon3.
  */
 
-#define RX_LE_SIZE             512
+#define RX_LE_SIZE             1024
 #define RX_LE_BYTES            (RX_LE_SIZE*sizeof(struct sky2_rx_le))
-#define RX_MAX_PENDING         (RX_LE_SIZE/2 - 2)
+#define RX_MAX_PENDING         (RX_LE_SIZE/6 - 2)
 #define RX_DEF_PENDING         RX_MAX_PENDING
 #define RX_SKB_ALIGN           8
 #define RX_BUF_WRITE           16
@@ -74,7 +73,6 @@
 
 #define STATUS_RING_SIZE       2048    /* 2 ports * (TX + 2*RX) */
 #define STATUS_LE_BYTES                (STATUS_RING_SIZE*sizeof(struct sky2_status_le))
-#define ETH_JUMBO_MTU          9000
 #define TX_WATCHDOG            (5 * HZ)
 #define NAPI_WEIGHT            64
 #define PHY_RETRIES            1000
@@ -90,7 +88,7 @@ static int debug = -1;                /* defaults above */
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
 
-static int copybreak __read_mostly = 256;
+static int copybreak __read_mostly = 128;
 module_param(copybreak, int, 0);
 MODULE_PARM_DESC(copybreak, "Receive copy threshold");
 
@@ -769,9 +767,16 @@ static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2)
        struct sky2_tx_le *le = sky2->tx_le + sky2->tx_prod;
 
        sky2->tx_prod = RING_NEXT(sky2->tx_prod, TX_RING_SIZE);
+       le->ctrl = 0;
        return le;
 }
 
+static inline struct tx_ring_info *tx_le_re(struct sky2_port *sky2,
+                                           struct sky2_tx_le *le)
+{
+       return sky2->tx_ring + (le - sky2->tx_le);
+}
+
 /* Update chip's next pointer */
 static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q, u16 idx)
 {
@@ -786,6 +791,7 @@ static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2)
 {
        struct sky2_rx_le *le = sky2->rx_le + sky2->rx_put;
        sky2->rx_put = RING_NEXT(sky2->rx_put, RX_LE_SIZE);
+       le->ctrl = 0;
        return le;
 }
 
@@ -795,17 +801,16 @@ static inline u32 high32(dma_addr_t a)
        return sizeof(a) > sizeof(u32) ? (a >> 16) >> 16 : 0;
 }
 
-/* Build description to hardware about buffer */
-static void sky2_rx_add(struct sky2_port *sky2, dma_addr_t map)
+/* Build description to hardware for one receive segment */
+static void sky2_rx_add(struct sky2_port *sky2,  u8 op,
+                       dma_addr_t map, unsigned len)
 {
        struct sky2_rx_le *le;
        u32 hi = high32(map);
-       u16 len = sky2->rx_bufsize;
 
        if (sky2->rx_addr64 != hi) {
                le = sky2_next_rx(sky2);
                le->addr = cpu_to_le32(hi);
-               le->ctrl = 0;
                le->opcode = OP_ADDR64 | HW_OWNER;
                sky2->rx_addr64 = high32(map + len);
        }
@@ -813,11 +818,53 @@ static void sky2_rx_add(struct sky2_port *sky2, dma_addr_t map)
        le = sky2_next_rx(sky2);
        le->addr = cpu_to_le32((u32) map);
        le->length = cpu_to_le16(len);
-       le->ctrl = 0;
-       le->opcode = OP_PACKET | HW_OWNER;
+       le->opcode = op | HW_OWNER;
+}
+
+/* Build description to hardware for one possibly fragmented skb */
+static void sky2_rx_submit(struct sky2_port *sky2,
+                          const struct rx_ring_info *re)
+{
+       int i;
+
+       sky2_rx_add(sky2, OP_PACKET, re->data_addr, sky2->rx_data_size);
+
+       for (i = 0; i < skb_shinfo(re->skb)->nr_frags; i++)
+               sky2_rx_add(sky2, OP_BUFFER, re->frag_addr[i], PAGE_SIZE);
 }
 
 
+static void sky2_rx_map_skb(struct pci_dev *pdev, struct rx_ring_info *re,
+                           unsigned size)
+{
+       struct sk_buff *skb = re->skb;
+       int i;
+
+       re->data_addr = pci_map_single(pdev, skb->data, size, PCI_DMA_FROMDEVICE);
+       pci_unmap_len_set(re, data_size, size);
+
+       for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
+               re->frag_addr[i] = pci_map_page(pdev,
+                                               skb_shinfo(skb)->frags[i].page,
+                                               skb_shinfo(skb)->frags[i].page_offset,
+                                               skb_shinfo(skb)->frags[i].size,
+                                               PCI_DMA_FROMDEVICE);
+}
+
+static void sky2_rx_unmap_skb(struct pci_dev *pdev, struct rx_ring_info *re)
+{
+       struct sk_buff *skb = re->skb;
+       int i;
+
+       pci_unmap_single(pdev, re->data_addr, pci_unmap_len(re, data_size),
+                        PCI_DMA_FROMDEVICE);
+
+       for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
+               pci_unmap_page(pdev, re->frag_addr[i],
+                              skb_shinfo(skb)->frags[i].size,
+                              PCI_DMA_FROMDEVICE);
+}
+
 /* Tell chip where to start receive checksum.
  * Actually has two checksums, but set both same to avoid possible byte
  * order problems.
@@ -877,12 +924,10 @@ static void sky2_rx_clean(struct sky2_port *sky2)
 
        memset(sky2->rx_le, 0, RX_LE_BYTES);
        for (i = 0; i < sky2->rx_pending; i++) {
-               struct ring_info *re = sky2->rx_ring + i;
+               struct rx_ring_info *re = sky2->rx_ring + i;
 
                if (re->skb) {
-                       pci_unmap_single(sky2->hw->pdev,
-                                        re->mapaddr, sky2->rx_bufsize,
-                                        PCI_DMA_FROMDEVICE);
+                       sky2_rx_unmap_skb(sky2->hw->pdev, re);
                        kfree_skb(re->skb);
                        re->skb = NULL;
                }
@@ -936,13 +981,13 @@ static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp
        struct sky2_hw *hw = sky2->hw;
        u16 port = sky2->port;
 
-       spin_lock_bh(&sky2->tx_lock);
+       netif_tx_lock_bh(dev);
 
        sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_ON);
        sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_ON);
        sky2->vlgrp = grp;
 
-       spin_unlock_bh(&sky2->tx_lock);
+       netif_tx_unlock_bh(dev);
 }
 
 static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
@@ -951,50 +996,69 @@ static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
        struct sky2_hw *hw = sky2->hw;
        u16 port = sky2->port;
 
-       spin_lock_bh(&sky2->tx_lock);
+       netif_tx_lock_bh(dev);
 
        sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_OFF);
        sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_OFF);
        if (sky2->vlgrp)
                sky2->vlgrp->vlan_devices[vid] = NULL;
 
-       spin_unlock_bh(&sky2->tx_lock);
+       netif_tx_unlock_bh(dev);
 }
 #endif
 
 /*
+ * Allocate an skb for receiving. If the MTU is large enough
+ * make the skb non-linear with a fragment list of pages.
+ *
  * It appears the hardware has a bug in the FIFO logic that
  * cause it to hang if the FIFO gets overrun and the receive buffer
  * is not 64 byte aligned. The buffer returned from netdev_alloc_skb is
  * aligned except if slab debugging is enabled.
  */
-static inline struct sk_buff *sky2_alloc_skb(struct net_device *dev,
-                                            unsigned int length,
-                                            gfp_t gfp_mask)
+static struct sk_buff *sky2_rx_alloc(struct sky2_port *sky2)
 {
        struct sk_buff *skb;
+       unsigned long p;
+       int i;
 
-       skb = __netdev_alloc_skb(dev, length + RX_SKB_ALIGN, gfp_mask);
-       if (likely(skb)) {
-               unsigned long p = (unsigned long) skb->data;
-               skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p);
+       skb = netdev_alloc_skb(sky2->netdev, sky2->rx_data_size + RX_SKB_ALIGN);
+       if (!skb)
+               goto nomem;
+
+       p = (unsigned long) skb->data;
+       skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p);
+
+       for (i = 0; i < sky2->rx_nfrags; i++) {
+               struct page *page = alloc_page(GFP_ATOMIC);
+
+               if (!page)
+                       goto free_partial;
+               skb_fill_page_desc(skb, i, page, 0, PAGE_SIZE);
        }
 
        return skb;
+free_partial:
+       kfree_skb(skb);
+nomem:
+       return NULL;
 }
 
 /*
  * Allocate and setup receiver buffer pool.
- * In case of 64 bit dma, there are 2X as many list elements
- * available as ring entries
- * and need to reserve one list element so we don't wrap around.
+ * Normal case this ends up creating one list element for skb
+ * in the receive ring. Worst case if using large MTU and each
+ * allocation falls on a different 64 bit region, that results
+ * in 6 list elements per ring entry.
+ * One element is used for checksum enable/disable, and one
+ * extra to avoid wrap.
  */
 static int sky2_rx_start(struct sky2_port *sky2)
 {
        struct sky2_hw *hw = sky2->hw;
+       struct rx_ring_info *re;
        unsigned rxq = rxqaddr[sky2->port];
-       int i;
-       unsigned thresh;
+       unsigned i, size, space, thresh;
 
        sky2->rx_put = sky2->rx_next = 0;
        sky2_qset(hw, rxq);
@@ -1007,27 +1071,56 @@ static int sky2_rx_start(struct sky2_port *sky2)
        sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1);
 
        rx_set_checksum(sky2);
+
+       /* Space needed for frame data + headers rounded up */
+       size = ALIGN(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8)
+               + 8;
+
+       /* Stopping point for hardware truncation */
+       thresh = (size - 8) / sizeof(u32);
+
+       /* Account for overhead of skb - to avoid order > 0 allocation */
+       space = SKB_DATA_ALIGN(size) + NET_SKB_PAD
+               + sizeof(struct skb_shared_info);
+
+       sky2->rx_nfrags = space >> PAGE_SHIFT;
+       BUG_ON(sky2->rx_nfrags > ARRAY_SIZE(re->frag_addr));
+
+       if (sky2->rx_nfrags != 0) {
+               /* Compute residue after pages */
+               space = sky2->rx_nfrags << PAGE_SHIFT;
+
+               if (space < size)
+                       size -= space;
+               else
+                       size = 0;
+
+               /* Optimize to handle small packets and headers */
+               if (size < copybreak)
+                       size = copybreak;
+               if (size < ETH_HLEN)
+                       size = ETH_HLEN;
+       }
+       sky2->rx_data_size = size;
+
+       /* Fill Rx ring */
        for (i = 0; i < sky2->rx_pending; i++) {
-               struct ring_info *re = sky2->rx_ring + i;
+               re = sky2->rx_ring + i;
 
-               re->skb = sky2_alloc_skb(sky2->netdev, sky2->rx_bufsize,
-                                        GFP_KERNEL);
+               re->skb = sky2_rx_alloc(sky2);
                if (!re->skb)
                        goto nomem;
 
-               re->mapaddr = pci_map_single(hw->pdev, re->skb->data,
-                                            sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
-               sky2_rx_add(sky2, re->mapaddr);
+               sky2_rx_map_skb(hw->pdev, re, sky2->rx_data_size);
+               sky2_rx_submit(sky2, re);
        }
 
-
        /*
         * The receiver hangs if it receives frames larger than the
         * packet buffer. As a workaround, truncate oversize frames, but
         * the register is limited to 9 bits, so if you do frames > 2052
         * you better get the MTU right!
         */
-       thresh = (sky2->rx_bufsize - 8) / sizeof(u32);
        if (thresh > 0x1ff)
                sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_OFF);
        else {
@@ -1035,7 +1128,6 @@ static int sky2_rx_start(struct sky2_port *sky2)
                sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_ON);
        }
 
-
        /* Tell chip about available buffers */
        sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put);
        return 0;
@@ -1094,7 +1186,7 @@ static int sky2_up(struct net_device *dev)
                goto err_out;
        memset(sky2->rx_le, 0, RX_LE_BYTES);
 
-       sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct ring_info),
+       sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct rx_ring_info),
                                GFP_KERNEL);
        if (!sky2->rx_ring)
                goto err_out;
@@ -1124,7 +1216,8 @@ static int sky2_up(struct net_device *dev)
        sky2_qset(hw, txqaddr[port]);
 
        /* Set almost empty threshold */
-       if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev == 1)
+       if (hw->chip_id == CHIP_ID_YUKON_EC_U
+           && hw->chip_rev == CHIP_REV_YU_EC_U_A0)
                sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), 0x1a0);
 
        sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
@@ -1195,8 +1288,6 @@ static unsigned tx_le_req(const struct sk_buff *skb)
  * A single packet can generate multiple list elements, and
  * the number of ring elements will probably be less than the number
  * of list elements used.
- *
- * No BH disabling for tx_lock here (like tg3)
  */
 static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
 {
@@ -1210,27 +1301,8 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
        u16 mss;
        u8 ctrl;
 
-       /* No BH disabling for tx_lock here.  We are running in BH disabled
-        * context and TX reclaim runs via poll inside of a software
-        * interrupt, and no related locks in IRQ processing.
-        */
-       if (!spin_trylock(&sky2->tx_lock))
-               return NETDEV_TX_LOCKED;
-
-       if (unlikely(tx_avail(sky2) < tx_le_req(skb))) {
-               /* There is a known but harmless race with lockless tx
-                * and netif_stop_queue.
-                */
-               if (!netif_queue_stopped(dev)) {
-                       netif_stop_queue(dev);
-                       if (net_ratelimit())
-                               printk(KERN_WARNING PFX "%s: ring full when queue awake!\n",
-                                      dev->name);
-               }
-               spin_unlock(&sky2->tx_lock);
-
-               return NETDEV_TX_BUSY;
-       }
+       if (unlikely(tx_avail(sky2) < tx_le_req(skb)))
+               return NETDEV_TX_BUSY;
 
        if (unlikely(netif_msg_tx_queued(sky2)))
                printk(KERN_DEBUG "%s: tx queued, slot %u, len %d\n",
@@ -1240,13 +1312,10 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
        mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
        addr64 = high32(mapping);
 
-       re = sky2->tx_ring + sky2->tx_prod;
-
        /* Send high bits if changed or crosses boundary */
        if (addr64 != sky2->tx_addr64 || high32(mapping + len) != sky2->tx_addr64) {
                le = get_tx_le(sky2);
                le->addr = cpu_to_le32(addr64);
-               le->ctrl = 0;
                le->opcode = OP_ADDR64 | HW_OWNER;
                sky2->tx_addr64 = high32(mapping + len);
        }
@@ -1262,7 +1331,6 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
                        le = get_tx_le(sky2);
                        le->addr = cpu_to_le32(mss);
                        le->opcode = OP_LRGLEN | HW_OWNER;
-                       le->ctrl = 0;
                        sky2->tx_last_mss = mss;
                }
        }
@@ -1275,7 +1343,6 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
                        le = get_tx_le(sky2);
                        le->addr = 0;
                        le->opcode = OP_VLAN|HW_OWNER;
-                       le->ctrl = 0;
                } else
                        le->opcode |= OP_VLAN;
                le->length = cpu_to_be16(vlan_tx_tag_get(skb));
@@ -1312,13 +1379,13 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
        le->ctrl = ctrl;
        le->opcode = mss ? (OP_LARGESEND | HW_OWNER) : (OP_PACKET | HW_OWNER);
 
-       /* Record the transmit mapping info */
+       re = tx_le_re(sky2, le);
        re->skb = skb;
        pci_unmap_addr_set(re, mapaddr, mapping);
+       pci_unmap_len_set(re, maplen, len);
 
        for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-               skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-               struct tx_ring_info *fre;
+               const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
                mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset,
                                       frag->size, PCI_DMA_TODEVICE);
@@ -1337,12 +1404,12 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
                le->ctrl = ctrl;
                le->opcode = OP_BUFFER | HW_OWNER;
 
-               fre = sky2->tx_ring
-                       + RING_NEXT((re - sky2->tx_ring) + i, TX_RING_SIZE);
-               pci_unmap_addr_set(fre, mapaddr, mapping);
+               re = tx_le_re(sky2, le);
+               re->skb = skb;
+               pci_unmap_addr_set(re, mapaddr, mapping);
+               pci_unmap_len_set(re, maplen, frag->size);
        }
 
-       re->idx = sky2->tx_prod;
        le->ctrl |= EOP;
 
        if (tx_avail(sky2) <= MAX_SKB_TX_LE)
@@ -1350,8 +1417,6 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
 
        sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod);
 
-       spin_unlock(&sky2->tx_lock);
-
        dev->trans_start = jiffies;
        return NETDEV_TX_OK;
 }
@@ -1360,59 +1425,59 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
  * Free ring elements from starting at tx_cons until "done"
  *
  * NB: the hardware will tell us about partial completion of multi-part
- *     buffers; these are deferred until completion.
+ *     buffers so make sure not to free skb to early.
  */
 static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
 {
        struct net_device *dev = sky2->netdev;
        struct pci_dev *pdev = sky2->hw->pdev;
-       u16 nxt, put;
-       unsigned i;
+       unsigned idx;
 
        BUG_ON(done >= TX_RING_SIZE);
 
-       if (unlikely(netif_msg_tx_done(sky2)))
-               printk(KERN_DEBUG "%s: tx done, up to %u\n",
-                      dev->name, done);
-
-       for (put = sky2->tx_cons; put != done; put = nxt) {
-               struct tx_ring_info *re = sky2->tx_ring + put;
-               struct sk_buff *skb = re->skb;
-
-               nxt = re->idx;
-               BUG_ON(nxt >= TX_RING_SIZE);
-               prefetch(sky2->tx_ring + nxt);
-
-               /* Check for partial status */
-               if (tx_dist(put, done) < tx_dist(put, nxt))
+       for (idx = sky2->tx_cons; idx != done;
+            idx = RING_NEXT(idx, TX_RING_SIZE)) {
+               struct sky2_tx_le *le = sky2->tx_le + idx;
+               struct tx_ring_info *re = sky2->tx_ring + idx;
+
+               switch(le->opcode & ~HW_OWNER) {
+               case OP_LARGESEND:
+               case OP_PACKET:
+                       pci_unmap_single(pdev,
+                                        pci_unmap_addr(re, mapaddr),
+                                        pci_unmap_len(re, maplen),
+                                        PCI_DMA_TODEVICE);
                        break;
-
-               skb = re->skb;
-               pci_unmap_single(pdev, pci_unmap_addr(re, mapaddr),
-                                skb_headlen(skb), PCI_DMA_TODEVICE);
-
-               for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-                       struct tx_ring_info *fre;
-                       fre = sky2->tx_ring + RING_NEXT(put + i, TX_RING_SIZE);
-                       pci_unmap_page(pdev, pci_unmap_addr(fre, mapaddr),
-                                      skb_shinfo(skb)->frags[i].size,
+               case OP_BUFFER:
+                       pci_unmap_page(pdev, pci_unmap_addr(re, mapaddr),
+                                      pci_unmap_len(re, maplen),
                                       PCI_DMA_TODEVICE);
+                       break;
                }
 
-               dev_kfree_skb(skb);
+               if (le->ctrl & EOP) {
+                       if (unlikely(netif_msg_tx_done(sky2)))
+                               printk(KERN_DEBUG "%s: tx done %u\n",
+                                      dev->name, idx);
+                       dev_kfree_skb(re->skb);
+               }
+
+               le->opcode = 0; /* paranoia */
        }
 
-       sky2->tx_cons = put;
+       sky2->tx_cons = idx;
        if (tx_avail(sky2) > MAX_SKB_TX_LE + 4)
                netif_wake_queue(dev);
 }
 
 /* Cleanup all untransmitted buffers, assume transmitter not running */
-static void sky2_tx_clean(struct sky2_port *sky2)
+static void sky2_tx_clean(struct net_device *dev)
 {
-       spin_lock_bh(&sky2->tx_lock);
+       struct sky2_port *sky2 = netdev_priv(dev);
+
+       netif_tx_lock_bh(dev);
        sky2_tx_complete(sky2, sky2->tx_prod);
-       spin_unlock_bh(&sky2->tx_lock);
+       netif_tx_unlock_bh(dev);
 }
 
 /* Network shutdown */
@@ -1443,6 +1508,13 @@ static int sky2_down(struct net_device *dev)
        sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL),
                     RB_RST_SET | RB_DIS_OP_MD);
 
+       /* WA for dev. #4.209 */
+       if (hw->chip_id == CHIP_ID_YUKON_EC_U
+           && hw->chip_rev == CHIP_REV_YU_EC_U_A1)
+               sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
+                            sky2->speed != SPEED_1000 ?
+                            TX_STFW_ENA : TX_STFW_DIS);
+
        ctrl = gma_read16(hw, port, GM_GP_CTRL);
        ctrl &= ~(GM_GPCR_TX_ENA | GM_GPCR_RX_ENA);
        gma_write16(hw, port, GM_GP_CTRL, ctrl);
@@ -1489,7 +1561,7 @@ static int sky2_down(struct net_device *dev)
 
        synchronize_irq(hw->pdev->irq);
 
-       sky2_tx_clean(sky2);
+       sky2_tx_clean(dev);
        sky2_rx_clean(sky2);
 
        pci_free_consistent(hw->pdev, RX_LE_BYTES,
@@ -1624,22 +1696,33 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux)
                return -1;
        }
 
-       if (hw->chip_id != CHIP_ID_YUKON_FE &&
-           gm_phy_read(hw, port, PHY_MARV_1000T_STAT) & PHY_B_1000S_MSF) {
-               printk(KERN_ERR PFX "%s: master/slave fault",
-                      sky2->netdev->name);
-               return -1;
-       }
-
        if (!(aux & PHY_M_PS_SPDUP_RES)) {
                printk(KERN_ERR PFX "%s: speed/duplex mismatch",
                       sky2->netdev->name);
                return -1;
        }
 
-       sky2->duplex = (aux & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;
-
        sky2->speed = sky2_phy_speed(hw, aux);
+       if (sky2->speed == SPEED_1000) {
+               u16 ctl2 = gm_phy_read(hw, port, PHY_MARV_1000T_CTRL);
+               u16 lpa2 = gm_phy_read(hw, port, PHY_MARV_1000T_STAT);
+               if (lpa2  & PHY_B_1000S_MSF) {
+                       printk(KERN_ERR PFX "%s: master/slave fault",
+                              sky2->netdev->name);
+                       return -1;
+               }
+
+               if ((ctl2 & PHY_M_1000C_AFD) && (lpa2 & PHY_B_1000S_LP_FD))
+                       sky2->duplex = DUPLEX_FULL;
+               else
+                       sky2->duplex = DUPLEX_HALF;
+       } else {
+               u16 adv = gm_phy_read(hw, port, PHY_MARV_AUNE_ADV);
+               if ((aux & adv) & PHY_AN_FULL)
+                       sky2->duplex = DUPLEX_FULL;
+               else
+                       sky2->duplex = DUPLEX_HALF;
+       }
 
        /* Pause bits are offset (9..8) */
        if (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)
@@ -1730,31 +1813,22 @@ static void sky2_tx_timeout(struct net_device *dev)
        } else if (report != sky2->tx_cons) {
                printk(KERN_INFO PFX "status report lost?\n");
 
-               spin_lock_bh(&sky2->tx_lock);
+               netif_tx_lock_bh(dev);
                sky2_tx_complete(sky2, report);
-               spin_unlock_bh(&sky2->tx_lock);
+               netif_tx_unlock_bh(dev);
        } else {
                printk(KERN_INFO PFX "hardware hung? flushing\n");
 
                sky2_write32(hw, Q_ADDR(txq, Q_CSR), BMU_STOP);
                sky2_write32(hw, Y2_QADDR(txq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
 
-               sky2_tx_clean(sky2);
+               sky2_tx_clean(dev);
 
                sky2_qset(hw, txq);
                sky2_prefetch_init(hw, txq, sky2->tx_le_map, TX_RING_SIZE - 1);
        }
 }
 
-
-/* Want receive buffer size to be multiple of 64 bits
- * and incl room for vlan and truncation
- */
-static inline unsigned sky2_buf_size(int mtu)
-{
-       return ALIGN(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8;
-}
-
 static int sky2_change_mtu(struct net_device *dev, int new_mtu)
 {
        struct sky2_port *sky2 = netdev_priv(dev);
@@ -1789,7 +1863,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
        sky2_rx_clean(sky2);
 
        dev->mtu = new_mtu;
-       sky2->rx_bufsize = sky2_buf_size(new_mtu);
+
        mode = DATA_BLIND_VAL(DATA_BLIND_DEF) |
                GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF);
 
@@ -1815,16 +1889,100 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
        return err;
 }
 
+/* For small just reuse existing skb for next receive */
+static struct sk_buff *receive_copy(struct sky2_port *sky2,
+                                   const struct rx_ring_info *re,
+                                   unsigned length)
+{
+       struct sk_buff *skb;
+
+       skb = netdev_alloc_skb(sky2->netdev, length + 2);
+       if (likely(skb)) {
+               skb_reserve(skb, 2);
+               pci_dma_sync_single_for_cpu(sky2->hw->pdev, re->data_addr,
+                                           length, PCI_DMA_FROMDEVICE);
+               memcpy(skb->data, re->skb->data, length);
+               skb->ip_summed = re->skb->ip_summed;
+               skb->csum = re->skb->csum;
+               pci_dma_sync_single_for_device(sky2->hw->pdev, re->data_addr,
+                                              length, PCI_DMA_FROMDEVICE);
+               re->skb->ip_summed = CHECKSUM_NONE;
+               __skb_put(skb, length);
+       }
+       return skb;
+}
+
+/* Adjust length of skb with fragments to match received data */
+static void skb_put_frags(struct sk_buff *skb, unsigned int hdr_space,
+                         unsigned int length)
+{
+       int i, num_frags;
+       unsigned int size;
+
+       /* put header into skb */
+       size = min(length, hdr_space);
+       skb->tail += size;
+       skb->len += size;
+       length -= size;
+
+       num_frags = skb_shinfo(skb)->nr_frags;
+       for (i = 0; i < num_frags; i++) {
+               skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+               if (length == 0) {
+                       /* don't need this page */
+                       __free_page(frag->page);
+                       --skb_shinfo(skb)->nr_frags;
+               } else {
+                       size = min(length, (unsigned) PAGE_SIZE);
+
+                       frag->size = size;
+                       skb->data_len += size;
+                       skb->truesize += size;
+                       skb->len += size;
+                       length -= size;
+               }
+       }
+}
+
+/* Normal packet - take skb from ring element and put in a new one  */
+static struct sk_buff *receive_new(struct sky2_port *sky2,
+                                  struct rx_ring_info *re,
+                                  unsigned int length)
+{
+       struct sk_buff *skb, *nskb;
+       unsigned hdr_space = sky2->rx_data_size;
+
+       pr_debug(PFX "receive new length=%d\n", length);
+
+       /* Don't be tricky about reusing pages (yet) */
+       nskb = sky2_rx_alloc(sky2);
+       if (unlikely(!nskb))
+               return NULL;
+
+       skb = re->skb;
+       sky2_rx_unmap_skb(sky2->hw->pdev, re);
+
+       prefetch(skb->data);
+       re->skb = nskb;
+       sky2_rx_map_skb(sky2->hw->pdev, re, hdr_space);
+
+       if (skb_shinfo(skb)->nr_frags)
+               skb_put_frags(skb, hdr_space, length);
+       else
+               skb_put(skb, hdr_space);
+       return skb;
+}
+
 /*
  * Receive one packet.
- * For small packets or errors, just reuse existing skb.
  * For larger packets, get new buffer.
  */
 static struct sk_buff *sky2_receive(struct net_device *dev,
                                    u16 length, u32 status)
 {
        struct sky2_port *sky2 = netdev_priv(dev);
-       struct ring_info *re = sky2->rx_ring + sky2->rx_next;
+       struct rx_ring_info *re = sky2->rx_ring + sky2->rx_next;
        struct sk_buff *skb = NULL;
 
        if (unlikely(netif_msg_rx_status(sky2)))
@@ -1843,40 +2001,12 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
        if (length > dev->mtu + ETH_HLEN)
                goto oversize;
 
-       if (length < copybreak) {
-               skb = netdev_alloc_skb(dev, length + 2);
-               if (!skb)
-                       goto resubmit;
-
-               skb_reserve(skb, 2);
-               pci_dma_sync_single_for_cpu(sky2->hw->pdev, re->mapaddr,
-                                           length, PCI_DMA_FROMDEVICE);
-               memcpy(skb->data, re->skb->data, length);
-               skb->ip_summed = re->skb->ip_summed;
-               skb->csum = re->skb->csum;
-               pci_dma_sync_single_for_device(sky2->hw->pdev, re->mapaddr,
-                                              length, PCI_DMA_FROMDEVICE);
-       } else {
-               struct sk_buff *nskb;
-
-               nskb = sky2_alloc_skb(dev, sky2->rx_bufsize, GFP_ATOMIC);
-               if (!nskb)
-                       goto resubmit;
-
-               skb = re->skb;
-               re->skb = nskb;
-               pci_unmap_single(sky2->hw->pdev, re->mapaddr,
-                                sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
-               prefetch(skb->data);
-
-               re->mapaddr = pci_map_single(sky2->hw->pdev, nskb->data,
-                                            sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
-       }
-
-       skb_put(skb, length);
+       if (length < copybreak)
+               skb = receive_copy(sky2, re, length);
+       else
+               skb = receive_new(sky2, re, length);
 resubmit:
-       re->skb->ip_summed = CHECKSUM_NONE;
-       sky2_rx_add(sky2, re->mapaddr);
+       sky2_rx_submit(sky2, re);
 
        return skb;
 
@@ -1909,9 +2039,9 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
        struct sky2_port *sky2 = netdev_priv(dev);
 
        if (netif_running(dev)) {
-               spin_lock(&sky2->tx_lock);
+               netif_tx_lock(dev);
                sky2_tx_complete(sky2, last);
-               spin_unlock(&sky2->tx_lock);
+               netif_tx_unlock(dev);
        }
 }
 
@@ -2082,7 +2212,7 @@ static void sky2_hw_intr(struct sky2_hw *hw)
 
                sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
                sky2_pci_write16(hw, PCI_STATUS,
-                                     pci_err | PCI_STATUS_ERROR_BITS);
+                                pci_err | PCI_STATUS_ERROR_BITS);
                sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
        }
 
@@ -2090,7 +2220,8 @@ static void sky2_hw_intr(struct sky2_hw *hw)
                /* PCI-Express uncorrectable Error occurred */
                u32 pex_err;
 
-               pex_err = sky2_pci_read32(hw, PEX_UNC_ERR_STAT);
+               pex_err = sky2_pci_read32(hw,
+                                         hw->err_cap + PCI_ERR_UNCOR_STATUS);
 
                if (net_ratelimit())
                        printk(KERN_ERR PFX "%s: pci express error (0x%x)\n",
@@ -2098,15 +2229,20 @@ static void sky2_hw_intr(struct sky2_hw *hw)
 
                /* clear the interrupt */
                sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
-               sky2_pci_write32(hw, PEX_UNC_ERR_STAT,
-                                      0xffffffffUL);
+               sky2_pci_write32(hw,
+                                hw->err_cap + PCI_ERR_UNCOR_STATUS,
+                                0xffffffffUL);
                sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
 
-               if (pex_err & PEX_FATAL_ERRORS) {
+
+               /* In case of fatal error mask off to keep from getting stuck */
+               if (pex_err & (PCI_ERR_UNC_POISON_TLP | PCI_ERR_UNC_FCP
+                              | PCI_ERR_UNC_DLP)) {
                        u32 hwmsk = sky2_read32(hw, B0_HWE_IMSK);
                        hwmsk &= ~Y2_IS_PCI_EXP;
                        sky2_write32(hw, B0_HWE_IMSK, hwmsk);
                }
+
        }
 
        if (status & Y2_HWE_L1_MASK)
@@ -2287,6 +2423,7 @@ static int sky2_reset(struct sky2_hw *hw)
        u16 status;
        u8 t8;
        int i;
+       u32 msk;
 
        sky2_write8(hw, B0_CTST, CS_RST_CLR);
 
@@ -2327,9 +2464,13 @@ static int sky2_reset(struct sky2_hw *hw)
        sky2_write8(hw, B0_CTST, CS_MRST_CLR);
 
        /* clear any PEX errors */
-       if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP))
-               sky2_pci_write32(hw, PEX_UNC_ERR_STAT, 0xffffffffUL);
-
+       if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP)) {
+               hw->err_cap = pci_find_ext_capability(hw->pdev, PCI_EXT_CAP_ID_ERR);
+               if (hw->err_cap)
+                       sky2_pci_write32(hw,
+                                        hw->err_cap + PCI_ERR_UNCOR_STATUS,
+                                        0xffffffffUL);
+       }
 
        hw->pmd_type = sky2_read8(hw, B2_PMD_TYP);
        hw->ports = 1;
@@ -2386,7 +2527,10 @@ static int sky2_reset(struct sky2_hw *hw)
                sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS2), SK_RI_TO_53);
        }
 
-       sky2_write32(hw, B0_HWE_IMSK, Y2_HWE_ALL_MASK);
+       msk = Y2_HWE_ALL_MASK;
+       if (!hw->err_cap)
+               msk &= ~Y2_IS_PCI_EXP;
+       sky2_write32(hw, B0_HWE_IMSK, msk);
 
        for (i = 0; i < hw->ports; i++)
                sky2_gmac_reset(hw, i);
@@ -3102,7 +3246,6 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
        sky2->hw = hw;
        sky2->msg_enable = netif_msg_init(debug, default_msg);
 
-       spin_lock_init(&sky2->tx_lock);
        /* Auto speed and flow control */
        sky2->autoneg = AUTONEG_ENABLE;
        sky2->tx_pause = 1;
@@ -3115,13 +3258,11 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
        spin_lock_init(&sky2->phy_lock);
        sky2->tx_pending = TX_DEF_PENDING;
        sky2->rx_pending = RX_DEF_PENDING;
-       sky2->rx_bufsize = sky2_buf_size(ETH_DATA_LEN);
 
        hw->dev[port] = dev;
 
        sky2->port = port;
 
-       dev->features |= NETIF_F_LLTX;
        if (hw->chip_id != CHIP_ID_YUKON_EC_U)
                dev->features |= NETIF_F_TSO;
        if (highmem)
@@ -3316,6 +3457,14 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
        if (!dev)
                goto err_out_free_pci;
 
+       if (!disable_msi && pci_enable_msi(pdev) == 0) {
+               err = sky2_test_msi(hw);
+               if (err == -EOPNOTSUPP)
+                       pci_disable_msi(pdev);
+               else if (err)
+                       goto err_out_free_netdev;
+       }
+
        err = register_netdev(dev);
        if (err) {
                printk(KERN_ERR PFX "%s: cannot register net device\n",
@@ -3323,6 +3472,14 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
                goto err_out_free_netdev;
        }
 
+       err = request_irq(pdev->irq,  sky2_intr, IRQF_SHARED, dev->name, hw);
+       if (err) {
+               printk(KERN_ERR PFX "%s: cannot assign irq %d\n",
+                      pci_name(pdev), pdev->irq);
+               goto err_out_unregister;
+       }
+       sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
+
        sky2_show_addr(dev);
 
        if (hw->ports > 1 && (dev1 = sky2_init_netdev(hw, 1, using_dac))) {
@@ -3337,23 +3494,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
                }
        }
 
-       if (!disable_msi && pci_enable_msi(pdev) == 0) {
-               err = sky2_test_msi(hw);
-               if (err == -EOPNOTSUPP)
-                       pci_disable_msi(pdev);
-               else if (err)
-                       goto err_out_unregister;
-       }
-
-       err = request_irq(pdev->irq,  sky2_intr, IRQF_SHARED, DRV_NAME, hw);
-       if (err) {
-               printk(KERN_ERR PFX "%s: cannot assign irq %d\n",
-                      pci_name(pdev), pdev->irq);
-               goto err_out_unregister;
-       }
-
-       sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
-
        setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) hw);
        sky2_idle_start(hw);
 
@@ -3363,10 +3503,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
 
 err_out_unregister:
        pci_disable_msi(pdev);
-       if (dev1) {
-               unregister_netdev(dev1);
-               free_netdev(dev1);
-       }
        unregister_netdev(dev);
 err_out_free_netdev:
        free_netdev(dev);
index 4c13c371bc217518be652ef9e868ecedf0d72525..f66109a96d95b0b2f13dfeba2c02f13241507a8d 100644 (file)
@@ -4,24 +4,17 @@
 #ifndef _SKY2_H
 #define _SKY2_H
 
-/* PCI config registers */
+#define ETH_JUMBO_MTU          9000    /* Maximum MTU supported */
+
+/* PCI device specific config registers */
 enum {
        PCI_DEV_REG1    = 0x40,
        PCI_DEV_REG2    = 0x44,
-       PCI_DEV_STATUS  = 0x7c,
        PCI_DEV_REG3    = 0x80,
        PCI_DEV_REG4    = 0x84,
        PCI_DEV_REG5    = 0x88,
 };
 
-enum {
-       PEX_DEV_CAP     = 0xe4,
-       PEX_DEV_CTRL    = 0xe8,
-       PEX_DEV_STA     = 0xea,
-       PEX_LNK_STAT    = 0xf2,
-       PEX_UNC_ERR_STAT= 0x104,
-};
-
 /* Yukon-2 */
 enum pci_dev_reg_1 {
        PCI_Y2_PIG_ENA   = 1<<31, /* Enable Plug-in-Go (YUKON-2) */
@@ -70,39 +63,6 @@ enum pci_dev_reg_4 {
                               PCI_STATUS_REC_MASTER_ABORT | \
                               PCI_STATUS_REC_TARGET_ABORT | \
                               PCI_STATUS_PARITY)
-
-enum pex_dev_ctrl {
-       PEX_DC_MAX_RRS_MSK      = 7<<12, /* Bit 14..12: Max. Read Request Size */
-       PEX_DC_EN_NO_SNOOP      = 1<<11,/* Enable No Snoop */
-       PEX_DC_EN_AUX_POW       = 1<<10,/* Enable AUX Power */
-       PEX_DC_EN_PHANTOM       = 1<<9, /* Enable Phantom Functions */
-       PEX_DC_EN_EXT_TAG       = 1<<8, /* Enable Extended Tag Field */
-       PEX_DC_MAX_PLS_MSK      = 7<<5, /* Bit  7.. 5:  Max. Payload Size Mask */
-       PEX_DC_EN_REL_ORD       = 1<<4, /* Enable Relaxed Ordering */
-       PEX_DC_EN_UNS_RQ_RP     = 1<<3, /* Enable Unsupported Request Reporting */
-       PEX_DC_EN_FAT_ER_RP     = 1<<2, /* Enable Fatal Error Reporting */
-       PEX_DC_EN_NFA_ER_RP     = 1<<1, /* Enable Non-Fatal Error Reporting */
-       PEX_DC_EN_COR_ER_RP     = 1<<0, /* Enable Correctable Error Reporting */
-};
-#define  PEX_DC_MAX_RD_RQ_SIZE(x) (((x)<<12) & PEX_DC_MAX_RRS_MSK)
-
-/* PEX_UNC_ERR_STAT     PEX Uncorrectable Errors Status Register (Yukon-2) */
-enum pex_err {
-       PEX_UNSUP_REQ   = 1<<20, /* Unsupported Request Error */
-
-       PEX_MALFOR_TLP  = 1<<18, /* Malformed TLP */
-
-       PEX_UNEXP_COMP  = 1<<16, /* Unexpected Completion */
-
-       PEX_COMP_TO     = 1<<14, /* Completion Timeout */
-       PEX_FLOW_CTRL_P = 1<<13, /* Flow Control Protocol Error */
-       PEX_POIS_TLP    = 1<<12, /* Poisoned TLP */
-
-       PEX_DATA_LINK_P = 1<<4, /* Data Link Protocol Error */
-       PEX_FATAL_ERRORS= (PEX_MALFOR_TLP | PEX_FLOW_CTRL_P | PEX_DATA_LINK_P),
-};
-
-
 enum csr_regs {
        B0_RAP          = 0x0000,
        B0_CTST         = 0x0004,
@@ -1816,12 +1776,14 @@ struct sky2_status_le {
 struct tx_ring_info {
        struct sk_buff  *skb;
        DECLARE_PCI_UNMAP_ADDR(mapaddr);
-       u16             idx;
+       DECLARE_PCI_UNMAP_ADDR(maplen);
 };
 
-struct ring_info {
+struct rx_ring_info {
        struct sk_buff  *skb;
-       dma_addr_t      mapaddr;
+       dma_addr_t      data_addr;
+       DECLARE_PCI_UNMAP_ADDR(data_size);
+       dma_addr_t      frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT];
 };
 
 struct sky2_port {
@@ -1831,7 +1793,6 @@ struct sky2_port {
        u32                  msg_enable;
        spinlock_t           phy_lock;
 
-       spinlock_t           tx_lock  ____cacheline_aligned_in_smp;
        struct tx_ring_info  *tx_ring;
        struct sky2_tx_le    *tx_le;
        u16                  tx_cons;           /* next le to check */
@@ -1841,13 +1802,15 @@ struct sky2_port {
        u16                  tx_last_mss;
        u32                  tx_tcpsum;
 
-       struct ring_info     *rx_ring ____cacheline_aligned_in_smp;
+       struct rx_ring_info  *rx_ring ____cacheline_aligned_in_smp;
        struct sky2_rx_le    *rx_le;
        u32                  rx_addr64;
        u16                  rx_next;           /* next re to check */
        u16                  rx_put;            /* next le index to use */
        u16                  rx_pending;
-       u16                  rx_bufsize;
+       u16                  rx_data_size;
+       u16                  rx_nfrags;
+
 #ifdef SKY2_VLAN_TAG_USED
        u16                  rx_tag;
        struct vlan_group    *vlgrp;
@@ -1873,6 +1836,7 @@ struct sky2_hw {
        struct net_device    *dev[2];
 
        int                  pm_cap;
+       int                  err_cap;
        u8                   chip_id;
        u8                   chip_rev;
        u8                   pmd_type;
index cc240adb72690304c58b129abcf1fbef0af4b128..1397fc55cf688c345899ea19a4f12271d0662287 100644 (file)
@@ -317,7 +317,7 @@ spider_net_init_chain(struct spider_net_card *card,
                                     SPIDER_NET_DESCR_SIZE,
                                     direction);
 
-               if (buf == DMA_ERROR_CODE)
+               if (pci_dma_mapping_error(buf))
                        goto iommu_error;
 
                descr->bus_addr = buf;
@@ -420,7 +420,7 @@ spider_net_prepare_rx_descr(struct spider_net_card *card,
        buf = pci_map_single(card->pdev, descr->skb->data,
                        SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE);
        descr->buf_addr = buf;
-       if (buf == DMA_ERROR_CODE) {
+       if (pci_dma_mapping_error(buf)) {
                dev_kfree_skb_any(descr->skb);
                if (netif_msg_rx_err(card) && net_ratelimit())
                        pr_err("Could not iommu-map rx buffer\n");
@@ -649,7 +649,7 @@ spider_net_prepare_tx_descr(struct spider_net_card *card,
        dma_addr_t buf;
 
        buf = pci_map_single(card->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
-       if (buf == DMA_ERROR_CODE) {
+       if (pci_dma_mapping_error(buf)) {
                if (netif_msg_tx_err(card) && net_ratelimit())
                        pr_err("could not iommu-map packet (%p, %i). "
                                  "Dropping packet\n", skb->data, skb->len);
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 bc0face01d25aa2c53f0ce95db2f0f2cf83fbca6..151a2e10e4f3dc980720dcbd277dd240ea84174a 100644 (file)
@@ -697,7 +697,7 @@ static int tun_chr_fasync(int fd, struct file *file, int on)
                return ret;
 
        if (on) {
-               ret = f_setown(file, current->pid, 0);
+               ret = __f_setown(file, task_pid(current), PIDTYPE_PID, 0);
                if (ret)
                        return ret;
                tun->flags |= TUN_FASYNC;
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 ba737c6cebec643a6316a058a0ebc2e0f1ac7d72..39d09345027cbbc0680d95e7c863d09b7ed02b32 100644 (file)
@@ -5659,25 +5659,40 @@ static int airo_pci_resume(struct pci_dev *pdev)
 
 static int __init airo_init_module( void )
 {
-       int i, have_isa_dev = 0;
+       int i;
+#if 0
+       int have_isa_dev = 0;
+#endif
 
        airo_entry = create_proc_entry("aironet",
                                       S_IFDIR | airo_perm,
                                       proc_root_driver);
-        airo_entry->uid = proc_uid;
-        airo_entry->gid = proc_gid;
+
+       if (airo_entry) {
+               airo_entry->uid = proc_uid;
+               airo_entry->gid = proc_gid;
+       }
 
        for( i = 0; i < 4 && io[i] && irq[i]; i++ ) {
                airo_print_info("", "Trying to configure ISA adapter at irq=%d "
                        "io=0x%x", irq[i], io[i] );
                if (init_airo_card( irq[i], io[i], 0, NULL ))
+#if 0
                        have_isa_dev = 1;
+#else
+                       /* do nothing */ ;
+#endif
        }
 
 #ifdef CONFIG_PCI
        airo_print_info("", "Probing for PCI adapters");
-       pci_register_driver(&airo_driver);
+       i = pci_register_driver(&airo_driver);
        airo_print_info("", "Finished probing for PCI adapters");
+
+       if (i) {
+               remove_proc_entry("aironet", proc_root_driver);
+               return i;
+       }
 #endif
 
        /* Always exit with success, as we are a library module
index 97937809de095c911850d914a522d4375de5c44b..599e2fe76188534cedd9973f7ebfd0fb1fb03e6a 100644 (file)
@@ -150,7 +150,6 @@ that only one external action is invoked at a time.
 #include <linux/skbuff.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
-#define __KERNEL_SYSCALLS__
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
@@ -6275,7 +6274,9 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
        IPW_DEBUG_INFO("%s: Bound to %s\n", dev->name, pci_name(pci_dev));
 
        /* perform this after register_netdev so that dev->name is set */
-       sysfs_create_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
+       err = sysfs_create_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
+       if (err)
+               goto fail_unlock;
 
        /* If the RF Kill switch is disabled, go ahead and complete the
         * startup sequence */
@@ -6541,14 +6542,17 @@ static int __init ipw2100_init(void)
        printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT);
 
        ret = pci_register_driver(&ipw2100_pci_driver);
+       if (ret)
+               goto out;
 
        set_acceptable_latency("ipw2100", INFINITE_LATENCY);
 #ifdef CONFIG_IPW2100_DEBUG
        ipw2100_debug_level = debug;
-       driver_create_file(&ipw2100_pci_driver.driver,
-                          &driver_attr_debug_level);
+       ret = driver_create_file(&ipw2100_pci_driver.driver,
+                                &driver_attr_debug_level);
 #endif
 
+out:
        return ret;
 }
 
index 1fbda77cefc29bfb0bbe820314feabce0d2c9700..c2949b4367e51b5c632ee765c7b799b2f6ba1211 100644 (file)
 #include <asm/superio.h>
 #endif
 
-#include <asm/iosapic.h>
+#include <asm/ropes.h>
 #include "./iosapic_private.h"
 
 #define MODULE_NAME "iosapic"
@@ -692,6 +692,7 @@ static void iosapic_end_irq(unsigned int irq)
        DBG(KERN_DEBUG "end_irq(%d): eoi(%p, 0x%x)\n", irq,
                        vi->eoi_addr, vi->eoi_data);
        iosapic_eoi(vi->eoi_addr, vi->eoi_data);
+       cpu_end_irq(irq);
 }
 
 static unsigned int iosapic_startup_irq(unsigned int irq)
@@ -728,7 +729,7 @@ static struct hw_interrupt_type iosapic_interrupt_type = {
        .shutdown =     iosapic_disable_irq,
        .enable =       iosapic_enable_irq,
        .disable =      iosapic_disable_irq,
-       .ack =          no_ack_irq,
+       .ack =          cpu_ack_irq,
        .end =          iosapic_end_irq,
 #ifdef CONFIG_SMP
        .set_affinity = iosapic_set_affinity_irq,
index 3fe4a77fa16a2301f0cb5a3ff96a51bb0c27ca18..ba6769934c771718035f8ed35c2a99c89021afce 100644 (file)
@@ -46,9 +46,9 @@
 #include <asm/page.h>
 #include <asm/system.h>
 
+#include <asm/ropes.h>
 #include <asm/hardware.h>      /* for register_parisc_driver() stuff */
 #include <asm/parisc-device.h>
-#include <asm/iosapic.h>       /* for iosapic_register() */
 #include <asm/io.h>            /* read/write stuff */
 
 #undef DEBUG_LBA       /* general stuff */
 
 #define MODULE_NAME "LBA"
 
-#define LBA_FUNC_ID    0x0000  /* function id */
-#define LBA_FCLASS     0x0008  /* function class, bist, header, rev... */
-#define LBA_CAPABLE    0x0030  /* capabilities register */
-
-#define LBA_PCI_CFG_ADDR       0x0040  /* poke CFG address here */
-#define LBA_PCI_CFG_DATA       0x0048  /* read or write data here */
-
-#define LBA_PMC_MTLT   0x0050  /* Firmware sets this - read only. */
-#define LBA_FW_SCRATCH 0x0058  /* Firmware writes the PCI bus number here. */
-#define LBA_ERROR_ADDR 0x0070  /* On error, address gets logged here */
-
-#define LBA_ARB_MASK   0x0080  /* bit 0 enable arbitration. PAT/PDC enables */
-#define LBA_ARB_PRI    0x0088  /* firmware sets this. */
-#define LBA_ARB_MODE   0x0090  /* firmware sets this. */
-#define LBA_ARB_MTLT   0x0098  /* firmware sets this. */
-
-#define LBA_MOD_ID     0x0100  /* Module ID. PDC_PAT_CELL reports 4 */
-
-#define LBA_STAT_CTL   0x0108  /* Status & Control */
-#define   LBA_BUS_RESET                0x01    /*  Deassert PCI Bus Reset Signal */
-#define   CLEAR_ERRLOG         0x10    /*  "Clear Error Log" cmd */
-#define   CLEAR_ERRLOG_ENABLE  0x20    /*  "Clear Error Log" Enable */
-#define   HF_ENABLE    0x40    /*    enable HF mode (default is -1 mode) */
-
-#define LBA_LMMIO_BASE 0x0200  /* < 4GB I/O address range */
-#define LBA_LMMIO_MASK 0x0208
-
-#define LBA_GMMIO_BASE 0x0210  /* > 4GB I/O address range */
-#define LBA_GMMIO_MASK 0x0218
-
-#define LBA_WLMMIO_BASE        0x0220  /* All < 4GB ranges under the same *SBA* */
-#define LBA_WLMMIO_MASK        0x0228
-
-#define LBA_WGMMIO_BASE        0x0230  /* All > 4GB ranges under the same *SBA* */
-#define LBA_WGMMIO_MASK        0x0238
-
-#define LBA_IOS_BASE   0x0240  /* I/O port space for this LBA */
-#define LBA_IOS_MASK   0x0248
-
-#define LBA_ELMMIO_BASE        0x0250  /* Extra LMMIO range */
-#define LBA_ELMMIO_MASK        0x0258
-
-#define LBA_EIOS_BASE  0x0260  /* Extra I/O port space */
-#define LBA_EIOS_MASK  0x0268
-
-#define LBA_GLOBAL_MASK        0x0270  /* Mercury only: Global Address Mask */
-#define LBA_DMA_CTL    0x0278  /* firmware sets this */
-
-#define LBA_IBASE      0x0300  /* SBA DMA support */
-#define LBA_IMASK      0x0308
-
-/* FIXME: ignore DMA Hint stuff until we can measure performance */
-#define LBA_HINT_CFG   0x0310
-#define LBA_HINT_BASE  0x0380  /* 14 registers at every 8 bytes. */
-
-#define LBA_BUS_MODE   0x0620
-
-/* ERROR regs are needed for config cycle kluges */
-#define LBA_ERROR_CONFIG 0x0680
-#define     LBA_SMART_MODE 0x20
-#define LBA_ERROR_STATUS 0x0688
-#define LBA_ROPE_CTL     0x06A0
-
-#define LBA_IOSAPIC_BASE       0x800 /* Offset of IRQ logic */
-
 /* non-postable I/O port space, densely packed */
 #define LBA_PORT_BASE  (PCI_F_EXTEND | 0xfee00000UL)
 static void __iomem *astro_iop_base __read_mostly;
 
-#define ELROY_HVERS    0x782
-#define MERCURY_HVERS  0x783
-#define QUICKSILVER_HVERS      0x784
-
-static inline int IS_ELROY(struct parisc_device *d)
-{
-       return (d->id.hversion == ELROY_HVERS);
-}
-
-static inline int IS_MERCURY(struct parisc_device *d)
-{
-       return (d->id.hversion == MERCURY_HVERS);
-}
-
-static inline int IS_QUICKSILVER(struct parisc_device *d)
-{
-       return (d->id.hversion == QUICKSILVER_HVERS);
-}
-
-
-/*
-** lba_device: Per instance Elroy data structure
-*/
-struct lba_device {
-       struct pci_hba_data hba;
-
-       spinlock_t      lba_lock;
-       void            *iosapic_obj;
-
-#ifdef CONFIG_64BIT
-       void __iomem *  iop_base;    /* PA_VIEW - for IO port accessor funcs */
-#endif
-
-       int             flags;       /* state/functionality enabled */
-       int             hw_rev;      /* HW revision of chip */
-};
-
-
 static u32 lba_t32;
 
 /* lba flags */
@@ -1542,8 +1439,8 @@ lba_driver_probe(struct parisc_device *dev)
                default: version = "TR4+";
                }
 
-               printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n",
-                       MODULE_NAME, version, func_class & 0xf, dev->hpa.start);
+               printk(KERN_INFO "Elroy version %s (0x%x) found at 0x%lx\n",
+                      version, func_class & 0xf, dev->hpa.start);
 
                if (func_class < 2) {
                        printk(KERN_WARNING "Can't support LBA older than "
@@ -1563,14 +1460,18 @@ lba_driver_probe(struct parisc_device *dev)
                }
 
        } else if (IS_MERCURY(dev) || IS_QUICKSILVER(dev)) {
+               int major, minor;
+
                func_class &= 0xff;
-               version = kmalloc(6, GFP_KERNEL);
-               snprintf(version, 6, "TR%d.%d",(func_class >> 4),(func_class & 0xf));
+               major = func_class >> 4, minor = func_class & 0xf;
+
                /* We could use one printk for both Elroy and Mercury,
                  * but for the mask for func_class.
                  */ 
-               printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n",
-                      MODULE_NAME, version, func_class & 0xff, dev->hpa.start);
+               printk(KERN_INFO "%s version TR%d.%d (0x%x) found at 0x%lx\n",
+                      IS_MERCURY(dev) ? "Mercury" : "Quicksilver", major,
+                      minor, func_class, dev->hpa.start);
+
                cfg_ops = &mercury_cfg_ops;
        } else {
                printk(KERN_ERR "Unknown LBA found at 0x%lx\n", dev->hpa.start);
@@ -1600,6 +1501,7 @@ lba_driver_probe(struct parisc_device *dev)
        lba_dev->hba.dev = dev;
        lba_dev->iosapic_obj = tmp_obj;  /* save interrupt handle */
        lba_dev->hba.iommu = sba_get_iommu(dev);  /* get iommu data */
+       parisc_set_drvdata(dev, lba_dev);
 
        /* ------------ Second : initialize common stuff ---------- */
        pci_bios = &lba_bios_ops;
index bf00fa2537bbb6f8774611eb55481751bede4965..8dac2ba82bb95ee748d6b69d5f56e02f4b30e329 100644 (file)
@@ -684,7 +684,7 @@ int __init led_init(void)
        int ret;
 
        snprintf(lcd_text_default, sizeof(lcd_text_default),
-               "Linux %s", system_utsname.release);
+               "Linux %s", init_utsname()->release);
 
        /* Work around the buggy PDC of KittyHawk-machines */
        switch (CPU_HVERSION) {
index fad5a33bf0fa3ecac80bc57358cbd2327c2dbd68..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>
@@ -84,8 +84,7 @@
 
 static void deferred_poweroff(void *dummy)
 {
-       extern int cad_pid;     /* from kernel/sys.c */
-       if (kill_proc(cad_pid, SIGINT, 1)) {
+       if (kill_cad_pid(SIGINT, 1)) {
                /* just in case killing init process failed */
                machine_power_off();
        }
index 8b47328155112ee1631aec5d47e300e5464971c7..294c1117098d69d6a0a9c13e26cd9f4727fbf528 100644 (file)
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 
+#include <asm/ropes.h>
+#include <asm/mckinley.h>      /* for proc_mckinley_root */
 #include <asm/runway.h>                /* for proc_runway_root */
 #include <asm/pdc.h>           /* for PDC_MODEL_* */
 #include <asm/pdcpat.h>                /* for is_pdc_pat() */
 #include <asm/parisc-device.h>
 
-
-/* declared in arch/parisc/kernel/setup.c */
-extern struct proc_dir_entry * proc_mckinley_root;
-
 #define MODULE_NAME "SBA"
 
-#ifdef CONFIG_PROC_FS
-/* depends on proc fs support. But costs CPU performance */
-#undef SBA_COLLECT_STATS
-#endif
-
 /*
 ** The number of debug flags is a clue - this code is fragile.
 ** Don't even think about messing with it unless you have
@@ -92,202 +85,12 @@ extern struct proc_dir_entry * proc_mckinley_root;
 #define DBG_RES(x...)
 #endif
 
-#if defined(CONFIG_64BIT)
-/* "low end" PA8800 machines use ZX1 chipset: PAT PDC and only run 64-bit */
-#define ZX1_SUPPORT
-#endif
-
 #define SBA_INLINE     __inline__
 
-
-/*
-** The number of pdir entries to "free" before issueing
-** a read to PCOM register to flush out PCOM writes.
-** Interacts with allocation granularity (ie 4 or 8 entries
-** allocated and free'd/purged at a time might make this
-** less interesting).
-*/
-#define DELAYED_RESOURCE_CNT   16
-
 #define DEFAULT_DMA_HINT_REG   0
 
-#define ASTRO_RUNWAY_PORT      0x582
-#define IKE_MERCED_PORT                0x803
-#define REO_MERCED_PORT                0x804
-#define REOG_MERCED_PORT       0x805
-#define PLUTO_MCKINLEY_PORT    0x880
-
-#define SBA_FUNC_ID    0x0000  /* function id */
-#define SBA_FCLASS     0x0008  /* function class, bist, header, rev... */
-
-#define IS_ASTRO(id)           ((id)->hversion == ASTRO_RUNWAY_PORT)
-#define IS_IKE(id)             ((id)->hversion == IKE_MERCED_PORT)
-#define IS_PLUTO(id)           ((id)->hversion == PLUTO_MCKINLEY_PORT)
-
-#define SBA_FUNC_SIZE 4096   /* SBA configuration function reg set */
-
-#define ASTRO_IOC_OFFSET       (32 * SBA_FUNC_SIZE)
-#define PLUTO_IOC_OFFSET       (1 * SBA_FUNC_SIZE)
-/* Ike's IOC's occupy functions 2 and 3 */
-#define IKE_IOC_OFFSET(p)      ((p+2) * SBA_FUNC_SIZE)
-
-#define IOC_CTRL          0x8  /* IOC_CTRL offset */
-#define IOC_CTRL_TC       (1 << 0) /* TOC Enable */
-#define IOC_CTRL_CE       (1 << 1) /* Coalesce Enable */
-#define IOC_CTRL_DE       (1 << 2) /* Dillon Enable */
-#define IOC_CTRL_RM       (1 << 8) /* Real Mode */
-#define IOC_CTRL_NC       (1 << 9) /* Non Coherent Mode */
-#define IOC_CTRL_D4       (1 << 11) /* Disable 4-byte coalescing */
-#define IOC_CTRL_DD       (1 << 13) /* Disable distr. LMMIO range coalescing */
-
-#define MAX_IOC                2       /* per Ike. Pluto/Astro only have 1. */
-
-#define ROPES_PER_IOC  8       /* per Ike half or Pluto/Astro */
-
-
-/*
-** Offsets into MBIB (Function 0 on Ike and hopefully Astro)
-** Firmware programs this stuff. Don't touch it.
-*/
-#define LMMIO_DIRECT0_BASE  0x300
-#define LMMIO_DIRECT0_MASK  0x308
-#define LMMIO_DIRECT0_ROUTE 0x310
-
-#define LMMIO_DIST_BASE  0x360
-#define LMMIO_DIST_MASK  0x368
-#define LMMIO_DIST_ROUTE 0x370
-
-#define IOS_DIST_BASE  0x390
-#define IOS_DIST_MASK  0x398
-#define IOS_DIST_ROUTE 0x3A0
-
-#define IOS_DIRECT_BASE        0x3C0
-#define IOS_DIRECT_MASK        0x3C8
-#define IOS_DIRECT_ROUTE 0x3D0
-
-/*
-** Offsets into I/O TLB (Function 2 and 3 on Ike)
-*/
-#define ROPE0_CTL      0x200  /* "regbus pci0" */
-#define ROPE1_CTL      0x208
-#define ROPE2_CTL      0x210
-#define ROPE3_CTL      0x218
-#define ROPE4_CTL      0x220
-#define ROPE5_CTL      0x228
-#define ROPE6_CTL      0x230
-#define ROPE7_CTL      0x238
-
-#define IOC_ROPE0_CFG  0x500   /* pluto only */
-#define   IOC_ROPE_AO    0x10  /* Allow "Relaxed Ordering" */
-
-
-
-#define HF_ENABLE      0x40
-
-
-#define IOC_IBASE      0x300   /* IO TLB */
-#define IOC_IMASK      0x308
-#define IOC_PCOM       0x310
-#define IOC_TCNFG      0x318
-#define IOC_PDIR_BASE  0x320
-
-/* AGP GART driver looks for this */
-#define SBA_IOMMU_COOKIE    0x0000badbadc0ffeeUL
-
-
-/*
-** IOC supports 4/8/16/64KB page sizes (see TCNFG register)
-** It's safer (avoid memory corruption) to keep DMA page mappings
-** equivalently sized to VM PAGE_SIZE.
-**
-** We really can't avoid generating a new mapping for each
-** page since the Virtual Coherence Index has to be generated
-** and updated for each page.
-**
-** PAGE_SIZE could be greater than IOVP_SIZE. But not the inverse.
-*/
-#define IOVP_SIZE      PAGE_SIZE
-#define IOVP_SHIFT     PAGE_SHIFT
-#define IOVP_MASK      PAGE_MASK
-
-#define SBA_PERF_CFG   0x708   /* Performance Counter stuff */
-#define SBA_PERF_MASK1 0x718
-#define SBA_PERF_MASK2 0x730
-
-
-/*
-** Offsets into PCI Performance Counters (functions 12 and 13)
-** Controlled by PERF registers in function 2 & 3 respectively.
-*/
-#define SBA_PERF_CNT1  0x200
-#define SBA_PERF_CNT2  0x208
-#define SBA_PERF_CNT3  0x210
-
-
-struct ioc {
-       void __iomem    *ioc_hpa;       /* I/O MMU base address */
-       char            *res_map;       /* resource map, bit == pdir entry */
-       u64             *pdir_base;     /* physical base address */
-       unsigned long   ibase;  /* pdir IOV Space base - shared w/lba_pci */
-       unsigned long   imask;  /* pdir IOV Space mask - shared w/lba_pci */
-#ifdef ZX1_SUPPORT
-       unsigned long   iovp_mask;      /* help convert IOVA to IOVP */
-#endif
-       unsigned long   *res_hint;      /* next avail IOVP - circular search */
-       spinlock_t      res_lock;
-       unsigned int    res_bitshift;   /* from the LEFT! */
-       unsigned int    res_size;       /* size of resource map in bytes */
-#ifdef SBA_HINT_SUPPORT
-/* FIXME : DMA HINTs not used */
-       unsigned long   hint_mask_pdir; /* bits used for DMA hints */
-       unsigned int    hint_shift_pdir;
-#endif
-#if DELAYED_RESOURCE_CNT > 0
-       int saved_cnt;
-       struct sba_dma_pair {
-               dma_addr_t      iova;
-               size_t          size;
-       } saved[DELAYED_RESOURCE_CNT];
-#endif
-
-#ifdef SBA_COLLECT_STATS
-#define SBA_SEARCH_SAMPLE      0x100
-       unsigned long avg_search[SBA_SEARCH_SAMPLE];
-       unsigned long avg_idx;  /* current index into avg_search */
-       unsigned long used_pages;
-       unsigned long msingle_calls;
-       unsigned long msingle_pages;
-       unsigned long msg_calls;
-       unsigned long msg_pages;
-       unsigned long usingle_calls;
-       unsigned long usingle_pages;
-       unsigned long usg_calls;
-       unsigned long usg_pages;
-#endif
-
-       /* STUFF We don't need in performance path */
-       unsigned int    pdir_size;      /* in bytes, determined by IOV Space size */
-};
-
-struct sba_device {
-       struct sba_device       *next;  /* list of SBA's in system */
-       struct parisc_device    *dev;   /* dev found in bus walk */
-       struct parisc_device_id *iodc;  /* data about dev from firmware */
-       const char              *name;
-       void __iomem            *sba_hpa; /* base address */
-       spinlock_t              sba_lock;
-       unsigned int            flags;  /* state/functionality enabled */
-       unsigned int            hw_rev;  /* HW revision of chip */
-
-       struct resource         chip_resv; /* MMIO reserved for chip */
-       struct resource         iommu_resv; /* MMIO reserved for iommu */
-
-       unsigned int            num_ioc;  /* number of on-board IOC's */
-       struct ioc              ioc[MAX_IOC];
-};
-
-
-static struct sba_device *sba_list;
+struct sba_device *sba_list;
+EXPORT_SYMBOL_GPL(sba_list);
 
 static unsigned long ioc_needs_fdc = 0;
 
@@ -300,8 +103,14 @@ static unsigned long piranha_bad_128k = 0;
 /* Looks nice and keeps the compiler happy */
 #define SBA_DEV(d) ((struct sba_device *) (d))
 
+#ifdef CONFIG_AGP_PARISC
+#define SBA_AGP_SUPPORT
+#endif /*CONFIG_AGP_PARISC*/
+
 #ifdef SBA_AGP_SUPPORT
-static int reserve_sba_gart = 1;
+static int sba_reserve_agpgart = 1;
+module_param(sba_reserve_agpgart, int, 1);
+MODULE_PARM_DESC(sba_reserve_agpgart, "Reserve half of IO pdir as AGPGART");
 #endif
 
 #define ROUNDUP(x,y) ((x + ((y)-1)) & ~((y)-1))
@@ -741,7 +550,7 @@ sba_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba,
        asm("lci 0(%%sr1, %1), %0" : "=r" (ci) : "r" (vba));
        pa |= (ci >> 12) & 0xff;  /* move CI (8 bits) into lowest byte */
 
-       pa |= 0x8000000000000000ULL;    /* set "valid" bit */
+       pa |= SBA_PDIR_VALID_BIT;       /* set "valid" bit */
        *pdir_ptr = cpu_to_le64(pa);    /* swap and store into I/O Pdir */
 
        /*
@@ -1498,6 +1307,10 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
        WRITE_REG(ioc->ibase | 31, ioc->ioc_hpa + IOC_PCOM);
 
 #ifdef SBA_AGP_SUPPORT
+{
+       struct klist_iter i;
+       struct device *dev = NULL;
+
        /*
        ** If an AGP device is present, only use half of the IOV space
        ** for PCI DMA.  Unfortunately we can't know ahead of time
@@ -1506,20 +1319,22 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
        ** We program the next pdir index after we stop w/ a key for
        ** the GART code to handshake on.
        */
-       device=NULL;
-       for (lba = sba->child; lba; lba = lba->sibling) {
+       klist_iter_init(&sba->dev.klist_children, &i);
+       while (dev = next_device(&i)) {
+               struct parisc_device *lba = to_parisc_device(dev);
                if (IS_QUICKSILVER(lba))
-                       break;
+                       agp_found = 1;
        }
+       klist_iter_exit(&sba->dev.klist_children, &i);
 
-       if (lba) {
-               DBG_INIT("%s: Reserving half of IOVA space for AGP GART support\n", __FUNCTION__);
+       if (agp_found && sba_reserve_agpgart) {
+               printk(KERN_INFO "%s: reserving %dMb of IOVA space for agpgart\n",
+                      __FUNCTION__, (iova_space_size/2) >> 20);
                ioc->pdir_size /= 2;
-               ((u64 *)ioc->pdir_base)[PDIR_INDEX(iova_space_size/2)] = SBA_IOMMU_COOKIE;
-       } else {
-               DBG_INIT("%s: No GART needed - no AGP controller found\n", __FUNCTION__);
+               ioc->pdir_base[PDIR_INDEX(iova_space_size/2)] = SBA_AGPGART_COOKIE;
        }
-#endif /* 0 */
+}
+#endif /*SBA_AGP_SUPPORT*/
 
 }
 
@@ -1701,7 +1516,7 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa,
        }
 #endif
 
-       if (!IS_PLUTO(sba_dev->iodc)) {
+       if (!IS_PLUTO(sba_dev->dev)) {
                ioc_ctl = READ_REG(sba_dev->sba_hpa+IOC_CTRL);
                DBG_INIT("%s() hpa 0x%lx ioc_ctl 0x%Lx ->",
                        __FUNCTION__, sba_dev->sba_hpa, ioc_ctl);
@@ -1718,9 +1533,8 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa,
 #endif
        } /* if !PLUTO */
 
-       if (IS_ASTRO(sba_dev->iodc)) {
+       if (IS_ASTRO(sba_dev->dev)) {
                int err;
-               /* PAT_PDC (L-class) also reports the same goofy base */
                sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, ASTRO_IOC_OFFSET);
                num_ioc = 1;
 
@@ -1730,13 +1544,9 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa,
                err = request_resource(&iomem_resource, &(sba_dev->chip_resv));
                BUG_ON(err < 0);
 
-       } else if (IS_PLUTO(sba_dev->iodc)) {
+       } else if (IS_PLUTO(sba_dev->dev)) {
                int err;
 
-               /* We use a negative value for IOC HPA so it gets 
-                 * corrected when we add it with IKE's IOC offset.
-                * Doesnt look clean, but fewer code. 
-                 */
                sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, PLUTO_IOC_OFFSET);
                num_ioc = 1;
 
@@ -1752,14 +1562,14 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa,
                err = request_resource(&iomem_resource, &(sba_dev->iommu_resv));
                WARN_ON(err < 0);
        } else {
-               /* IS_IKE (ie N-class, L3000, L1500) */
+               /* IKE, REO */
                sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, IKE_IOC_OFFSET(0));
                sba_dev->ioc[1].ioc_hpa = ioc_remap(sba_dev, IKE_IOC_OFFSET(1));
                num_ioc = 2;
 
                /* TODO - LOOKUP Ike/Stretch chipset mem map */
        }
-       /* XXX: What about Reo? */
+       /* XXX: What about Reo Grande? */
 
        sba_dev->num_ioc = num_ioc;
        for (i = 0; i < num_ioc; i++) {
@@ -1774,7 +1584,7 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa,
                         * Overrides bit 1 in DMA Hint Sets.
                         * Improves netperf UDP_STREAM by ~10% for bcm5701.
                         */
-                       if (IS_PLUTO(sba_dev->iodc)) {
+                       if (IS_PLUTO(sba_dev->dev)) {
                                void __iomem *rope_cfg;
                                unsigned long cfg_val;
 
@@ -1803,7 +1613,7 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa,
                                READ_REG(sba_dev->ioc[i].ioc_hpa + 0x400)
                        );
 
-               if (IS_PLUTO(sba_dev->iodc)) {
+               if (IS_PLUTO(sba_dev->dev)) {
                        sba_ioc_init_pluto(sba_dev->dev, &(sba_dev->ioc[i]), i);
                } else {
                        sba_ioc_init(sba_dev->dev, &(sba_dev->ioc[i]), i);
@@ -2067,7 +1877,7 @@ sba_driver_callback(struct parisc_device *dev)
        /* Read HW Rev First */
        func_class = READ_REG(sba_addr + SBA_FCLASS);
 
-       if (IS_ASTRO(&dev->id)) {
+       if (IS_ASTRO(dev)) {
                unsigned long fclass;
                static char astro_rev[]="Astro ?.?";
 
@@ -2078,11 +1888,11 @@ sba_driver_callback(struct parisc_device *dev)
                astro_rev[8] = '0' + (char) ((fclass & 0x18) >> 3);
                version = astro_rev;
 
-       } else if (IS_IKE(&dev->id)) {
+       } else if (IS_IKE(dev)) {
                static char ike_rev[] = "Ike rev ?";
                ike_rev[8] = '0' + (char) (func_class & 0xff);
                version = ike_rev;
-       } else if (IS_PLUTO(&dev->id)) {
+       } else if (IS_PLUTO(dev)) {
                static char pluto_rev[]="Pluto ?.?";
                pluto_rev[6] = '0' + (char) ((func_class & 0xf0) >> 4); 
                pluto_rev[8] = '0' + (char) (func_class & 0x0f); 
@@ -2097,7 +1907,7 @@ sba_driver_callback(struct parisc_device *dev)
                global_ioc_cnt = count_parisc_driver(&sba_driver);
 
                /* Astro and Pluto have one IOC per SBA */
-               if ((!IS_ASTRO(&dev->id)) || (!IS_PLUTO(&dev->id)))
+               if ((!IS_ASTRO(dev)) || (!IS_PLUTO(dev)))
                        global_ioc_cnt *= 2;
        }
 
@@ -2117,7 +1927,6 @@ sba_driver_callback(struct parisc_device *dev)
 
        sba_dev->dev = dev;
        sba_dev->hw_rev = func_class;
-       sba_dev->iodc = &dev->id;
        sba_dev->name = dev->name;
        sba_dev->sba_hpa = sba_addr;
 
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 43894ddec7dcfa9d4c8528703649baef60d9420b..fe800dc0be9f7fedfdf69e92ff262ebe0b51d787 100644 (file)
@@ -3374,10 +3374,6 @@ __setup("parport_init_mode=",parport_init_mode_setup);
 
 static int __init parport_pc_init(void)
 {
-#if defined(CONFIG_PPC_MERGE)
-       if (check_legacy_ioport(PARALLEL_BASE))
-               return -ENODEV;
-#endif
        if (parse_parport_params())
                return -EINVAL;
 
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 f2e0179962e2f85f6aae48db8bacc42c6ac9f700..3ac5b123215a09f17551531d106324e1e8ac9554 100644 (file)
@@ -1049,6 +1049,10 @@ static int __init isapnp_init(void)
                printk(KERN_INFO "isapnp: ISA Plug & Play support disabled\n");
                return 0;
        }
+#ifdef CONFIG_PPC_MERGE
+       if (check_legacy_ioport(_PIDXR) || check_legacy_ioport(_PNPWRP))
+               return -EINVAL;
+#endif
 #ifdef ISAPNP_REGION_OK
        if (!request_region(_PIDXR, 1, "isapnp index")) {
                printk(KERN_ERR "isapnp: Index Register 0x%x already used\n", _PIDXR);
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 2fa566fa6da4e287488fda979f2d3b72fe552f38..d7de175d53f08b0794170e08170edf5d2ea406d5 100644 (file)
@@ -1103,7 +1103,7 @@ tty3215_start(struct tty_struct *tty)
        }
 }
 
-static struct tty_operations tty3215_ops = {
+static const struct tty_operations tty3215_ops = {
        .open = tty3215_open,
        .close = tty3215_close,
        .write = tty3215_write,
index b4557fa30858038103825a70ae43402062dce96d..78f8bda81daee67e38fc651c6988b66b940890a8 100644 (file)
@@ -27,7 +27,7 @@ struct raw3270_fn fs3270_fn;
 
 struct fs3270 {
        struct raw3270_view view;
-       pid_t fs_pid;                   /* Pid of controlling program. */
+       struct pid *fs_pid;             /* Pid of controlling program. */
        int read_command;               /* ccw command to use for reads. */
        int write_command;              /* ccw command to use for writes. */
        int attention;                  /* Got attention. */
@@ -102,7 +102,7 @@ fs3270_restore_callback(struct raw3270_request *rq, void *data)
        fp = (struct fs3270 *) rq->view;
        if (rq->rc != 0 || rq->rescnt != 0) {
                if (fp->fs_pid)
-                       kill_proc(fp->fs_pid, SIGHUP, 1);
+                       kill_pid(fp->fs_pid, SIGHUP, 1);
        }
        fp->rdbuf_size = 0;
        raw3270_request_reset(rq);
@@ -173,7 +173,7 @@ fs3270_save_callback(struct raw3270_request *rq, void *data)
         */
        if (rq->rc != 0 || rq->rescnt == 0) {
                if (fp->fs_pid)
-                       kill_proc(fp->fs_pid, SIGHUP, 1);
+                       kill_pid(fp->fs_pid, SIGHUP, 1);
                fp->rdbuf_size = 0;
        } else
                fp->rdbuf_size = fp->rdbuf->size - rq->rescnt;
@@ -442,7 +442,7 @@ fs3270_open(struct inode *inode, struct file *filp)
                return PTR_ERR(fp);
 
        init_waitqueue_head(&fp->wait);
-       fp->fs_pid = current->pid;
+       fp->fs_pid = get_pid(task_pid(current));
        rc = raw3270_add_view(&fp->view, &fs3270_fn, minor);
        if (rc) {
                fs3270_free_view(&fp->view);
@@ -480,7 +480,8 @@ fs3270_close(struct inode *inode, struct file *filp)
        fp = filp->private_data;
        filp->private_data = NULL;
        if (fp) {
-               fp->fs_pid = 0;
+               put_pid(fp->fs_pid);
+               fp->fs_pid = NULL;
                raw3270_reset(&fp->view);
                raw3270_put_view(&fp->view);
                raw3270_del_view(&fp->view);
index f6cf9023039e352bed29b71ca0da273ecd8b6d24..6f43e04dbefdce1e57eee86bfd94960a7488d89d 100644 (file)
@@ -711,7 +711,7 @@ static struct sclp_register sclp_input_event =
        .receiver_fn = sclp_tty_receiver
 };
 
-static struct tty_operations sclp_ops = {
+static const struct tty_operations sclp_ops = {
        .open = sclp_tty_open,
        .close = sclp_tty_close,
        .write = sclp_tty_write,
index 54fba6f171883fda8384ab794adb77f761759991..723bf4191bfe2adb009c55d59797dfd98891f882 100644 (file)
@@ -655,7 +655,7 @@ __sclp_vt220_init(int early)
        return 0;
 }
 
-static struct tty_operations sclp_vt220_ops = {
+static const struct tty_operations sclp_vt220_ops = {
        .open = sclp_vt220_open,
        .close = sclp_vt220_close,
        .write = sclp_vt220_write,
index 06e2eeec8473dca2e3ff3c79ae5fab78014eac0c..4717c3611601f308094f588238a5b6c8c039cbd9 100644 (file)
@@ -1737,7 +1737,7 @@ tty3270_ioctl(struct tty_struct *tty, struct file *file,
        return kbd_ioctl(tp->kbd, file, cmd, arg);
 }
 
-static struct tty_operations tty3270_ops = {
+static const struct tty_operations tty3270_ops = {
        .open = tty3270_open,
        .close = tty3270_close,
        .write = tty3270_write,
index 479364d0332a062c2424fbf16728464fb3c29b7a..e088b5e287111b7268e322ad62dc838663d4815c 100644 (file)
@@ -208,7 +208,7 @@ s390_handle_mcck(void)
                 */
                __ctl_clear_bit(14, 24);        /* Disable WARNING MCH */
                if (xchg(&mchchk_wng_posted, 1) == 0)
-                       kill_proc(1, SIGPWR, 1);
+                       kill_cad_pid(SIGPWR, 1);
        }
 #endif
 
index 4fdb2c932210a80772d74c69636061734af334cf..a305d4091547f9180a367a26bc67d410d1e926cc 100644 (file)
@@ -2187,7 +2187,7 @@ static void do_softint(void *private_)
 #endif
 }
 
-static struct tty_operations aurora_ops = {
+static const struct tty_operations aurora_ops = {
        .open  = aurora_open,
        .close = aurora_close,
        .write = aurora_write,
index 1cc706e111193c9fb7f066416e7f8edd9f3b4a7b..d27e4f6d7045a3a5f21e38d6bab32455d83c3d8a 100644 (file)
@@ -4,9 +4,6 @@
  * Copyright (C) 2001 David S. Miller (davem@redhat.com)
  */
 
-#define __KERNEL_SYSCALLS__
-static int errno;
-
 #include <linux/kernel.h>
 #include <linux/kthread.h>
 #include <linux/sched.h>
@@ -200,7 +197,7 @@ static void do_envctrl_shutdown(struct bbc_cpu_temperature *tp)
        printk(KERN_CRIT "kenvctrld: Shutting down the system now.\n");
 
        shutting_down = 1;
-       if (execve("/sbin/shutdown", argv, envp) < 0)
+       if (kernel_execve("/sbin/shutdown", argv, envp) < 0)
                printk(KERN_CRIT "envctrl: shutdown execution failed\n");
 }
 
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 063e676a3ac046e5de17809cce433ca281b21dd5..728a133d0fc5b7c306443280e63d296e047cc5dc 100644 (file)
@@ -19,9 +19,6 @@
  *              Daniele Bellucci <bellucda@tiscali.it>
  */
 
-#define __KERNEL_SYSCALLS__
-static int errno;
-
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/kthread.h>
@@ -976,13 +973,15 @@ static void envctrl_do_shutdown(void)
                "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
        char *argv[] = { 
                "/sbin/shutdown", "-h", "now", NULL };  
+       int ret;
 
        if (inprog != 0)
                return;
 
        inprog = 1;
        printk(KERN_CRIT "kenvctrld: WARNING: Shutting down the system now.\n");
-       if (0 > execve("/sbin/shutdown", argv, envp)) {
+       ret = kernel_execve("/sbin/shutdown", argv, envp);
+       if (ret < 0) {
                printk(KERN_CRIT "kenvctrld: WARNING: system shutdown failed!\n"); 
                inprog = 0;  /* unlikely to succeed, but we could try again */
        }
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 ae4106458991890086cb81be16bbd91dbddfeabd..1b53afb1cb5768c4946e889987cd58ab1691be39 100644 (file)
@@ -933,8 +933,8 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
                        ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
                        ae->ad.bits.AttrType = be16_to_cpu(OS_NAME_VERSION);
                        sprintf(ae->un.OsNameVersion, "%s %s %s",
-                               system_utsname.sysname, system_utsname.release,
-                               system_utsname.version);
+                               init_utsname()->sysname, init_utsname()->release,
+                               init_utsname()->version);
                        len = strlen(ae->un.OsNameVersion);
                        len += (len & 3) ? (4 - (len & 3)) : 4;
                        ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len);
@@ -1052,7 +1052,7 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
                                                          size);
                                ae->ad.bits.AttrType = be16_to_cpu(HOST_NAME);
                                sprintf(ae->un.HostName, "%s",
-                                       system_utsname.nodename);
+                                       init_utsname()->nodename);
                                len = strlen(ae->un.HostName);
                                len += (len & 3) ? (4 - (len & 3)) : 4;
                                ae->ad.bits.AttrLen =
@@ -1140,7 +1140,7 @@ lpfc_fdmi_tmo_handler(struct lpfc_hba *phba)
 
        ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, FDMI_DID);
        if (ndlp) {
-               if (system_utsname.nodename[0] != '\0') {
+               if (init_utsname()->nodename[0] != '\0') {
                        lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_DHBA);
                } else {
                        mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60);
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 993a702422ec6e2e22175ea67e6c9bacb55ab093..bac853c5abb565dfeb11cc32ed910191f956a9c9 100644 (file)
@@ -1378,7 +1378,7 @@ void startup_console(void)
 #endif /* CONFIG_PM_LEGACY */
 
 
-static struct tty_operations rs_ops = {
+static const struct tty_operations rs_ops = {
        .open = rs_open,
        .close = rs_close,
        .write = rs_write,
index e80e70e9b12620487236f4ec56b3cb416104fc53..1b299e8c57cdf7071b5d155aa556d4ef05d51b29 100644 (file)
@@ -2424,7 +2424,7 @@ long console_360_init(long kmem_start, long kmem_end)
 */
 static int     baud_idx;
 
-static struct tty_operations rs_360_ops = {
+static const struct tty_operations rs_360_ops = {
        .owner = THIS_MODULE,
        .open = rs_360_open,
        .close = rs_360_close,
index 0ae9ced00ed4db899c591528a848f68a51c144a8..cc2a205d42300af96e6f0ecfda63172c5e151425 100644 (file)
@@ -320,8 +320,8 @@ static unsigned int serial_in(struct uart_8250_port *up, int offset)
 
        case UPIO_TSI:
                if (offset == UART_IIR) {
-                       tmp = readl((u32 *)(up->port.membase + UART_RX));
-                       return (cpu_to_le32(tmp) >> 8) & 0xff;
+                       tmp = readl(up->port.membase + (UART_IIR & ~3));
+                       return (tmp >> 16) & 0xff; /* UART_IIR % 4 == 2 */
                } else
                        return readb(up->port.membase + offset);
 
@@ -1896,6 +1896,17 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
                serial_outp(up, UART_EFR, efr);
        }
 
+#ifdef CONFIG_ARCH_OMAP15XX
+       /* Workaround to enable 115200 baud on OMAP1510 internal ports */
+       if (cpu_is_omap1510() && is_omap_port((unsigned int)up->port.membase)) {
+               if (baud == 115200) {
+                       quot = 1;
+                       serial_out(up, UART_OMAP_OSC_12M_SEL, 1);
+               } else
+                       serial_out(up, UART_OMAP_OSC_12M_SEL, 0);
+       }
+#endif
+
        if (up->capabilities & UART_NATSEMI) {
                /* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */
                serial_outp(up, UART_LCR, 0xe0);
@@ -1949,6 +1960,8 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
        case UPIO_AU:
                size = 0x100000;
                /* fall thru */
+       case UPIO_TSI:
+       case UPIO_MEM32:
        case UPIO_MEM:
                if (!up->port.mapbase)
                        break;
@@ -1984,6 +1997,8 @@ static void serial8250_release_std_resource(struct uart_8250_port *up)
        case UPIO_AU:
                size = 0x100000;
                /* fall thru */
+       case UPIO_TSI:
+       case UPIO_MEM32:
        case UPIO_MEM:
                if (!up->port.mapbase)
                        break;
@@ -2007,17 +2022,15 @@ static int serial8250_request_rsa_resource(struct uart_8250_port *up)
 {
        unsigned long start = UART_RSA_BASE << up->port.regshift;
        unsigned int size = 8 << up->port.regshift;
-       int ret = 0;
+       int ret = -EINVAL;
 
        switch (up->port.iotype) {
-       case UPIO_MEM:
-               ret = -EINVAL;
-               break;
-
        case UPIO_HUB6:
        case UPIO_PORT:
                start += up->port.iobase;
-               if (!request_region(start, size, "serial-rsa"))
+               if (request_region(start, size, "serial-rsa"))
+                       ret = 0;
+               else
                        ret = -EBUSY;
                break;
        }
@@ -2031,9 +2044,6 @@ static void serial8250_release_rsa_resource(struct uart_8250_port *up)
        unsigned int size = 8 << up->port.regshift;
 
        switch (up->port.iotype) {
-       case UPIO_MEM:
-               break;
-
        case UPIO_HUB6:
        case UPIO_PORT:
                release_region(up->port.iobase + offset, size);
@@ -2222,9 +2232,10 @@ static inline void wait_for_xmitr(struct uart_8250_port *up, int bits)
        /* Wait up to 1s for flow control if necessary */
        if (up->port.flags & UPF_CONS_FLOW) {
                tmout = 1000000;
-               while (--tmout &&
-                      ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0))
+               while (!(serial_in(up, UART_MSR) & UART_MSR_CTS) && --tmout) {
                        udelay(1);
+                       touch_nmi_watchdog();
+               }
        }
 }
 
@@ -2397,7 +2408,6 @@ int __init early_serial_setup(struct uart_port *port)
 /**
  *     serial8250_suspend_port - suspend one serial port
  *     @line:  serial line number
- *      @level: the level of port suspension, as per uart_suspend_port
  *
  *     Suspend one serial port.
  */
@@ -2409,7 +2419,6 @@ void serial8250_suspend_port(int line)
 /**
  *     serial8250_resume_port - resume one serial port
  *     @line:  serial line number
- *      @level: the level of port resumption, as per uart_resume_port
  *
  *     Resume one serial port.
  */
index 1ebe6b585d2d57d3c44b4d52bcceebb3b5fdfd78..c5d0addfda4f9404d97ffb9f39c46b9f5e79a7c8 100644 (file)
@@ -22,7 +22,6 @@
 #include <asm/hardware.h>
 #include <asm/parisc-device.h>
 #include <asm/io.h>
-#include <asm/serial.h> /* for LASI_BASE_BAUD */
 
 #include "8250.h"
 
@@ -54,7 +53,8 @@ serial_init_chip(struct parisc_device *dev)
 
        memset(&port, 0, sizeof(port));
        port.iotype     = UPIO_MEM;
-       port.uartclk    = LASI_BASE_BAUD * 16;
+       /* 7.272727MHz on Lasi.  Assumed the same for Dino, Wax and Timi. */
+       port.uartclk    = 7272727;
        port.mapbase    = address;
        port.membase    = ioremap_nocache(address, 16);
        port.irq        = dev->irq;
index 851e4839d6d97c0ad7501dea1798af815f5a00cb..4d0ff8f4a01b14024fed710507a1fd0013396780 100644 (file)
@@ -1789,6 +1789,7 @@ static void __devexit pciserial_remove_one(struct pci_dev *dev)
        pci_disable_device(dev);
 }
 
+#ifdef CONFIG_PM
 static int pciserial_suspend_one(struct pci_dev *dev, pm_message_t state)
 {
        struct serial_private *priv = pci_get_drvdata(dev);
@@ -1818,6 +1819,7 @@ static int pciserial_resume_one(struct pci_dev *dev)
        }
        return 0;
 }
+#endif
 
 static struct pci_device_id serial_pci_tbl[] = {
        {       PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
@@ -2375,8 +2377,10 @@ static struct pci_driver serial_pci_driver = {
        .name           = "serial",
        .probe          = pciserial_init_one,
        .remove         = __devexit_p(pciserial_remove_one),
+#ifdef CONFIG_PM
        .suspend        = pciserial_suspend_one,
        .resume         = pciserial_resume_one,
+#endif
        .id_table       = serial_pci_tbl,
 };
 
index 632f62d6ec7e773d09ac9c3a2fb9b5b693bb197b..71d907c8288b15a69214dc47f19578495da8a33c 100644 (file)
@@ -327,6 +327,19 @@ static const struct pnp_device_id pnp_dev_table[] = {
        {       "WACF004",              0       },
        {       "WACF005",              0       },
        {       "WACF006",              0       },
+       /* Compaq touchscreen */
+       {       "FPI2002",              0 },
+       /* Fujitsu Stylistic touchscreens */
+       {       "FUJ02B2",              0 },
+       {       "FUJ02B3",              0 },
+       /* Fujitsu Stylistic LT touchscreens */
+       {       "FUJ02B4",              0 },
+       /* Passive Fujitsu Stylistic touchscreens */
+       {       "FUJ02B6",              0 },
+       {       "FUJ02B7",              0 },
+       {       "FUJ02B8",              0 },
+       {       "FUJ02B9",              0 },
+       {       "FUJ02BC",              0 },
        /* Rockwell's (PORALiNK) 33600 INT PNP */
        {       "WCI0003",              0       },
        /* Unkown PnP modems */
index d926272a40db59ed23a956078e90b58a640f0e84..8edee745888a7371ab653534ed8e865ae4a83ccf 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.
@@ -556,10 +556,11 @@ config SERIAL_MUX
        default y
        ---help---
          Saying Y here will enable the hardware MUX serial driver for
-         the Nova and K class systems.  The hardware MUX is not 8250/16550 
-         compatible therefore the /dev/ttyB0 device is shared between the 
-         Serial MUX and the PDC software console.  The following steps 
-         need to be completed to use the Serial MUX:
+         the Nova, K class systems and D class with a 'remote control card'.
+         The hardware MUX is not 8250/16550 compatible therefore the
+         /dev/ttyB0 device is shared between the Serial MUX and the PDC
+         software console. The following steps need to be completed to use
+         the Serial MUX:
 
            1. create the device entry (mknod /dev/ttyB0 c 11 0)
            2. Edit the /etc/inittab to start a getty listening on /dev/ttyB0
@@ -667,7 +668,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 90ff96e3339bce5c8817f833e66d5d9580661a50..a0d6136deb9b0d47a8af0e970dd0b891876e7a5b 100644 (file)
@@ -46,6 +46,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/delay.h>
+#include <asm/fs_pd.h>
 
 #if defined(CONFIG_SERIAL_CPM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
 #define SUPPORT_SYSRQ
@@ -1022,15 +1023,17 @@ int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con)
 {
        struct resource *r;
        struct fs_uart_platform_info *pdata = pdev->dev.platform_data;
-       int idx = pdata->fs_no; /* It is UART_SMCx or UART_SCCx index */
+       int idx;        /* It is UART_SMCx or UART_SCCx index */
        struct uart_cpm_port *pinfo;
        int line;
        u32 mem, pram;
 
+        idx = pdata->fs_no = fs_uart_get_id(pdata);
+
        line = cpm_uart_id2nr(idx);
        if(line < 0) {
                printk(KERN_ERR"%s(): port %d is not registered", __FUNCTION__, idx);
-               return -1;
+               return -EINVAL;
        }
 
        pinfo = (struct uart_cpm_port *) &cpm_uart_ports[idx];
@@ -1044,11 +1047,11 @@ int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con)
 
        if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs")))
                return -EINVAL;
-       mem = r->start;
+       mem = (u32)ioremap(r->start, r->end - r->start + 1);
 
        if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram")))
                return -EINVAL;
-       pram = r->start;
+       pram = (u32)ioremap(r->start, r->end - r->start + 1);
 
        if(idx > fsid_smc2_uart) {
                pinfo->sccp = (scc_t *)mem;
@@ -1179,7 +1182,7 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
                pdata = pdev->dev.platform_data;
                if (pdata)
                        if (pdata->init_ioports)
-                               pdata->init_ioports();
+                               pdata->init_ioports(pdata);
 
                cpm_uart_drv_get_platform_data(pdev, 1);
        }
@@ -1189,11 +1192,7 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
        if (options) {
                uart_parse_options(options, &baud, &parity, &bits, &flow);
        } else {
-               bd_t *bd = (bd_t *) __res;
-
-               if (bd->bi_baudrate)
-                       baud = bd->bi_baudrate;
-               else
+               if ((baud = uart_baudrate()) == -1)
                        baud = 9600;
        }
 
@@ -1266,13 +1265,14 @@ static int cpm_uart_drv_probe(struct device *dev)
        }
 
        pdata = pdev->dev.platform_data;
-       pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n", cpm_uart_id2nr(pdata->fs_no));
 
        if ((ret = cpm_uart_drv_get_platform_data(pdev, 0)))
                return ret;
 
+       pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n", cpm_uart_id2nr(pdata->fs_no));
+
        if (pdata->init_ioports)
-                pdata->init_ioports();
+                pdata->init_ioports(pdata);
 
        ret = uart_add_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].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 ef3bb476c4326ab5c46b98cc43530a48c3312b93..b691d3e14754fa94a40ff0eac22889b2e2afda33 100644 (file)
@@ -40,6 +40,7 @@
 
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <asm/fs_pd.h>
 
 #include <linux/serial_core.h>
 #include <linux/kernel.h>
@@ -50,8 +51,9 @@
 
 void cpm_line_cr_cmd(int line, int cmd)
 {
-       volatile cpm_cpm2_t *cp = cpmp;
        ulong val;
+       volatile cpm_cpm2_t *cp = cpm2_map(im_cpm);
+
 
        switch (line) {
        case UART_SMC1:
@@ -84,11 +86,14 @@ void cpm_line_cr_cmd(int line, int cmd)
        }
        cp->cp_cpcr = val;
        while (cp->cp_cpcr & CPM_CR_FLG) ;
+
+       cpm2_unmap(cp);
 }
 
 void smc1_lineif(struct uart_cpm_port *pinfo)
 {
-       volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+       volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+       volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
 
        /* SMC1 is only on port D */
        io->iop_ppard |= 0x00c00000;
@@ -97,13 +102,17 @@ void smc1_lineif(struct uart_cpm_port *pinfo)
        io->iop_psord &= ~0x00c00000;
 
        /* Wire BRG1 to SMC1 */
-       cpm2_immr->im_cpmux.cmx_smr &= 0x0f;
+       cpmux->cmx_smr &= 0x0f;
        pinfo->brg = 1;
+
+       cpm2_unmap(cpmux);
+       cpm2_unmap(io);
 }
 
 void smc2_lineif(struct uart_cpm_port *pinfo)
 {
-       volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+       volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+       volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
 
        /* SMC2 is only on port A */
        io->iop_ppara |= 0x00c00000;
@@ -112,13 +121,17 @@ void smc2_lineif(struct uart_cpm_port *pinfo)
        io->iop_psora &= ~0x00c00000;
 
        /* Wire BRG2 to SMC2 */
-       cpm2_immr->im_cpmux.cmx_smr &= 0xf0;
+       cpmux->cmx_smr &= 0xf0;
        pinfo->brg = 2;
+
+       cpm2_unmap(cpmux);
+       cpm2_unmap(io);
 }
 
 void scc1_lineif(struct uart_cpm_port *pinfo)
 {
-       volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+       volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+       volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
 
        /* Use Port D for SCC1 instead of other functions.  */
        io->iop_ppard |= 0x00000003;
@@ -128,9 +141,12 @@ void scc1_lineif(struct uart_cpm_port *pinfo)
        io->iop_pdird |= 0x00000002;    /* Tx */
 
        /* Wire BRG1 to SCC1 */
-       cpm2_immr->im_cpmux.cmx_scr &= 0x00ffffff;
-       cpm2_immr->im_cpmux.cmx_scr |= 0x00000000;
+       cpmux->cmx_scr &= 0x00ffffff;
+       cpmux->cmx_scr |= 0x00000000;
        pinfo->brg = 1;
+
+       cpm2_unmap(cpmux);
+       cpm2_unmap(io);
 }
 
 void scc2_lineif(struct uart_cpm_port *pinfo)
@@ -143,43 +159,57 @@ void scc2_lineif(struct uart_cpm_port *pinfo)
         * be supported in a sane fashion.
         */
 #ifndef CONFIG_STX_GP3
-       volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+       volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+       volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
+
        io->iop_pparb |= 0x008b0000;
        io->iop_pdirb |= 0x00880000;
        io->iop_psorb |= 0x00880000;
        io->iop_pdirb &= ~0x00030000;
        io->iop_psorb &= ~0x00030000;
 #endif
-       cpm2_immr->im_cpmux.cmx_scr &= 0xff00ffff;
-       cpm2_immr->im_cpmux.cmx_scr |= 0x00090000;
+       cpmux->cmx_scr &= 0xff00ffff;
+       cpmux->cmx_scr |= 0x00090000;
        pinfo->brg = 2;
+
+       cpm2_unmap(cpmux);
+       cpm2_unmap(io);
 }
 
 void scc3_lineif(struct uart_cpm_port *pinfo)
 {
-       volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+       volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+       volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
+
        io->iop_pparb |= 0x008b0000;
        io->iop_pdirb |= 0x00880000;
        io->iop_psorb |= 0x00880000;
        io->iop_pdirb &= ~0x00030000;
        io->iop_psorb &= ~0x00030000;
-       cpm2_immr->im_cpmux.cmx_scr &= 0xffff00ff;
-       cpm2_immr->im_cpmux.cmx_scr |= 0x00001200;
+       cpmux->cmx_scr &= 0xffff00ff;
+       cpmux->cmx_scr |= 0x00001200;
        pinfo->brg = 3;
+
+       cpm2_unmap(cpmux);
+       cpm2_unmap(io);
 }
 
 void scc4_lineif(struct uart_cpm_port *pinfo)
 {
-       volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+       volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+       volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
 
        io->iop_ppard |= 0x00000600;
        io->iop_psord &= ~0x00000600;   /* Tx/Rx */
        io->iop_pdird &= ~0x00000200;   /* Rx */
        io->iop_pdird |= 0x00000400;    /* Tx */
 
-       cpm2_immr->im_cpmux.cmx_scr &= 0xffffff00;
-       cpm2_immr->im_cpmux.cmx_scr |= 0x0000001b;
+       cpmux->cmx_scr &= 0xffffff00;
+       cpmux->cmx_scr |= 0x0000001b;
        pinfo->brg = 4;
+
+       cpm2_unmap(cpmux);
+       cpm2_unmap(io);
 }
 
 /*
@@ -254,88 +284,103 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo)
 /* Setup any dynamic params in the uart desc */
 int cpm_uart_init_portdesc(void)
 {
+#if defined(CONFIG_SERIAL_CPM_SMC1) || defined(CONFIG_SERIAL_CPM_SMC2)
+       u32 addr;
+#endif
        pr_debug("CPM uart[-]:init portdesc\n");
 
        cpm_uart_nr = 0;
 #ifdef CONFIG_SERIAL_CPM_SMC1
-       cpm_uart_ports[UART_SMC1].smcp = (smc_t *) & cpm2_immr->im_smc[0];
-       cpm_uart_ports[UART_SMC1].smcup =
-           (smc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SMC1];
-       *(u16 *)(&cpm2_immr->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1;
+       cpm_uart_ports[UART_SMC1].smcp = (smc_t *) cpm2_map(im_smc[0]);
        cpm_uart_ports[UART_SMC1].port.mapbase =
-           (unsigned long)&cpm2_immr->im_smc[0];
+           (unsigned long)cpm_uart_ports[UART_SMC1].smcp;
+
+       cpm_uart_ports[UART_SMC1].smcup =
+           (smc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SMC1], PROFF_SMC_SIZE);
+       addr = (u16 *)cpm2_map_size(im_dprambase[PROFF_SMC1_BASE], 2);
+       *addr = PROFF_SMC1;
+       cpm2_unmap(addr);
+
        cpm_uart_ports[UART_SMC1].smcp->smc_smcm |= (SMCM_RX | SMCM_TX);
        cpm_uart_ports[UART_SMC1].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
-       cpm_uart_ports[UART_SMC1].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+       cpm_uart_ports[UART_SMC1].port.uartclk = uart_clock();
        cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1;
 #endif
 
 #ifdef CONFIG_SERIAL_CPM_SMC2
-       cpm_uart_ports[UART_SMC2].smcp = (smc_t *) & cpm2_immr->im_smc[1];
-       cpm_uart_ports[UART_SMC2].smcup =
-           (smc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SMC2];
-       *(u16 *)(&cpm2_immr->im_dprambase[PROFF_SMC2_BASE]) = PROFF_SMC2;
+       cpm_uart_ports[UART_SMC2].smcp = (smc_t *) cpm2_map(im_smc[1]);
        cpm_uart_ports[UART_SMC2].port.mapbase =
-           (unsigned long)&cpm2_immr->im_smc[1];
+           (unsigned long)cpm_uart_ports[UART_SMC2].smcp;
+
+       cpm_uart_ports[UART_SMC2].smcup =
+           (smc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SMC2], PROFF_SMC_SIZE);
+       addr = (u16 *)cpm2_map_size(im_dprambase[PROFF_SMC2_BASE], 2);
+       *addr = PROFF_SMC2;
+       cpm2_unmap(addr);
+
        cpm_uart_ports[UART_SMC2].smcp->smc_smcm |= (SMCM_RX | SMCM_TX);
        cpm_uart_ports[UART_SMC2].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
-       cpm_uart_ports[UART_SMC2].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+       cpm_uart_ports[UART_SMC2].port.uartclk = uart_clock();
        cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2;
 #endif
 
 #ifdef CONFIG_SERIAL_CPM_SCC1
-       cpm_uart_ports[UART_SCC1].sccp = (scc_t *) & cpm2_immr->im_scc[0];
-       cpm_uart_ports[UART_SCC1].sccup =
-           (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC1];
+       cpm_uart_ports[UART_SCC1].sccp = (scc_t *) cpm2_map(im_scc[0]);
        cpm_uart_ports[UART_SCC1].port.mapbase =
-           (unsigned long)&cpm2_immr->im_scc[0];
+           (unsigned long)cpm_uart_ports[UART_SCC1].sccp;
+       cpm_uart_ports[UART_SCC1].sccup =
+           (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC1], PROFF_SCC_SIZE);
+
        cpm_uart_ports[UART_SCC1].sccp->scc_sccm &=
            ~(UART_SCCM_TX | UART_SCCM_RX);
        cpm_uart_ports[UART_SCC1].sccp->scc_gsmrl &=
            ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
-       cpm_uart_ports[UART_SCC1].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+       cpm_uart_ports[UART_SCC1].port.uartclk = uart_clock();
        cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1;
 #endif
 
 #ifdef CONFIG_SERIAL_CPM_SCC2
-       cpm_uart_ports[UART_SCC2].sccp = (scc_t *) & cpm2_immr->im_scc[1];
-       cpm_uart_ports[UART_SCC2].sccup =
-           (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC2];
+       cpm_uart_ports[UART_SCC2].sccp = (scc_t *) cpm2_map(im_scc[1]);
        cpm_uart_ports[UART_SCC2].port.mapbase =
-           (unsigned long)&cpm2_immr->im_scc[1];
+           (unsigned long)cpm_uart_ports[UART_SCC2].sccp;
+       cpm_uart_ports[UART_SCC2].sccup =
+           (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC2], PROFF_SCC_SIZE);
+
        cpm_uart_ports[UART_SCC2].sccp->scc_sccm &=
            ~(UART_SCCM_TX | UART_SCCM_RX);
        cpm_uart_ports[UART_SCC2].sccp->scc_gsmrl &=
            ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
-       cpm_uart_ports[UART_SCC2].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+       cpm_uart_ports[UART_SCC2].port.uartclk = uart_clock();
        cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2;
 #endif
 
 #ifdef CONFIG_SERIAL_CPM_SCC3
-       cpm_uart_ports[UART_SCC3].sccp = (scc_t *) & cpm2_immr->im_scc[2];
-       cpm_uart_ports[UART_SCC3].sccup =
-           (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC3];
+       cpm_uart_ports[UART_SCC3].sccp = (scc_t *) cpm2_map(im_scc[2]);
        cpm_uart_ports[UART_SCC3].port.mapbase =
-           (unsigned long)&cpm2_immr->im_scc[2];
+           (unsigned long)cpm_uart_ports[UART_SCC3].sccp;
+       cpm_uart_ports[UART_SCC3].sccup =
+           (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC3], PROFF_SCC_SIZE);
+
        cpm_uart_ports[UART_SCC3].sccp->scc_sccm &=
            ~(UART_SCCM_TX | UART_SCCM_RX);
        cpm_uart_ports[UART_SCC3].sccp->scc_gsmrl &=
            ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
-       cpm_uart_ports[UART_SCC3].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+       cpm_uart_ports[UART_SCC3].port.uartclk = uart_clock();
        cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3;
 #endif
 
 #ifdef CONFIG_SERIAL_CPM_SCC4
-       cpm_uart_ports[UART_SCC4].sccp = (scc_t *) & cpm2_immr->im_scc[3];
-       cpm_uart_ports[UART_SCC4].sccup =
-           (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC4];
+       cpm_uart_ports[UART_SCC4].sccp = (scc_t *) cpm2_map(im_scc[3]);
        cpm_uart_ports[UART_SCC4].port.mapbase =
-           (unsigned long)&cpm2_immr->im_scc[3];
+           (unsigned long)cpm_uart_ports[UART_SCC4].sccp;
+       cpm_uart_ports[UART_SCC4].sccup =
+           (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC4], PROFF_SCC_SIZE);
+
        cpm_uart_ports[UART_SCC4].sccp->scc_sccm &=
            ~(UART_SCCM_TX | UART_SCCM_RX);
        cpm_uart_ports[UART_SCC4].sccp->scc_gsmrl &=
            ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
-       cpm_uart_ports[UART_SCC4].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+       cpm_uart_ports[UART_SCC4].port.uartclk = uart_clock();
        cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4;
 #endif
 
index 4793fecf8ecef8667c1d89c03d69b83681b91861..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
  * 
@@ -40,6 +40,6 @@ static inline void cpm_set_smc_fcr(volatile smc_uart_t * up)
        up->smc_tfcr = CPMFCR_GBL | CPMFCR_EB;
 }
 
-#define DPRAM_BASE     ((unsigned char *)&cpm2_immr->im_dprambase[0])
+#define DPRAM_BASE     ((unsigned char *)cpm_dpram_addr(0))
 
 #endif
index cabd048c8636060138b497b294bd9b4f6e9e1382..9851d9eff022a6e655db1011fa1f93cbd8cd03b4 100644 (file)
@@ -4825,7 +4825,7 @@ show_serial_version(void)
 
 /* rs_init inits the driver at boot (using the module_init chain) */
 
-static struct tty_operations rs_ops = {
+static const struct tty_operations rs_ops = {
        .open = rs_open,
        .close = rs_close,
        .write = rs_write,
index e7fe4bb46ecaf2c3dc169a2fb7862449fd6b0baf..28c9ce6f0bdc52023816e1e7dfc555debd08327f 100644 (file)
@@ -76,7 +76,7 @@
  */
 #define is_real_interrupt(irq) ((irq) != 0)
 
-#include <asm/serial.h>
+#define BASE_BAUD      115200
 
 /* Standard COM flags */
 #define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST)
@@ -86,7 +86,6 @@
  * standard enumeration mechanism.   Platforms that can find all
  * serial ports via mechanisms like ACPI or PCI need not supply it.
  */
-#undef SERIAL_PORT_DFNS
 #if defined(CONFIG_PLAT_USRV)
 
 #define SERIAL_PORT_DFNS                                               \
 #endif /* !CONFIG_PLAT_USRV */
 
 static struct old_serial_port old_serial_port[] = {
-       SERIAL_PORT_DFNS        /* defined in asm/serial.h */
+       SERIAL_PORT_DFNS
 };
 
 #define UART_NR        ARRAY_SIZE(old_serial_port)
index 832abd3c4706ddabe8a3a6c07d9caf0e2b8e139f..00d7859c167ec7c246c885cc918e2932cd1df69e 100644 (file)
@@ -1666,7 +1666,7 @@ static void show_serial_version(void)
        printk(mcfrs_drivername);
 }
 
-static struct tty_operations mcfrs_ops = {
+static const struct tty_operations mcfrs_ops = {
        .open = mcfrs_open,
        .close = mcfrs_close,
        .write = mcfrs_write,
index 5f7ba1adb309c20d6d2abe9a4847f77473e4519d..c67b05e9a45144c3410c23ed0050f4f70ec26c9a 100644 (file)
@@ -792,6 +792,7 @@ static int uart_set_info(struct uart_state *state,
                         * We failed anyway.
                         */
                        retval = -EBUSY;
+                       goto exit;  // Added to return the correct error -Ram Gupta
                }
        }
 
@@ -1662,16 +1663,16 @@ static int uart_line_info(char *buf, struct uart_driver *drv, int i)
        struct uart_port *port = state->port;
        char stat_buf[32];
        unsigned int status;
-       int ret;
+       int mmio, ret;
 
        if (!port)
                return 0;
 
+       mmio = port->iotype >= UPIO_MEM;
        ret = sprintf(buf, "%d: uart:%s %s%08lX irq:%d",
                        port->line, uart_type(port),
-                       port->iotype == UPIO_MEM ? "mmio:0x" : "port:",
-                       port->iotype == UPIO_MEM ? port->mapbase :
-                                               (unsigned long) port->iobase,
+                       mmio ? "mmio:0x" : "port:",
+                       mmio ? port->mapbase : (unsigned long) port->iobase,
                        port->irq);
 
        if (port->type == PORT_UNKNOWN) {
@@ -1939,6 +1940,9 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
        if (state->info && state->info->flags & UIF_INITIALIZED) {
                const struct uart_ops *ops = port->ops;
 
+               state->info->flags = (state->info->flags & ~UIF_INITIALIZED)
+                                    | UIF_SUSPENDED;
+
                spin_lock_irq(&port->lock);
                ops->stop_tx(port);
                ops->set_mctrl(port, 0);
@@ -2005,7 +2009,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
                console_start(port->cons);
        }
 
-       if (state->info && state->info->flags & UIF_INITIALIZED) {
+       if (state->info && state->info->flags & UIF_SUSPENDED) {
                const struct uart_ops *ops = port->ops;
                int ret;
 
@@ -2017,15 +2021,17 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
                        ops->set_mctrl(port, port->mctrl);
                        ops->start_tx(port);
                        spin_unlock_irq(&port->lock);
+                       state->info->flags |= UIF_INITIALIZED;
                } else {
                        /*
                         * Failed to resume - maybe hardware went away?
                         * Clear the "initialized" flag so we won't try
                         * to call the low level drivers shutdown method.
                         */
-                       state->info->flags &= ~UIF_INITIALIZED;
                        uart_shutdown(state);
                }
+
+               state->info->flags &= ~UIF_SUSPENDED;
        }
 
        mutex_unlock(&state->mutex);
@@ -2111,7 +2117,7 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state,
        }
 }
 
-static struct tty_operations uart_ops = {
+static const struct tty_operations uart_ops = {
        .open           = uart_open,
        .close          = uart_close,
        .write          = uart_write,
index cbf260bc225dc6c5bcd41758f22bb49bd3809550..00f9ffd6948969c000b1382b860eb916df25f61d 100644 (file)
@@ -80,23 +80,16 @@ module_param(buggy_uart, int, 0444);
 
 /* Table of multi-port card ID's */
 
-struct multi_id {
-       u_short manfid;
-       u_short prodid;
+struct serial_quirk {
+       unsigned int manfid;
+       unsigned int prodid;
        int multi;              /* 1 = multifunction, > 1 = # ports */
+       void (*config)(struct pcmcia_device *);
+       void (*setup)(struct pcmcia_device *, struct uart_port *);
+       void (*wakeup)(struct pcmcia_device *);
+       int (*post)(struct pcmcia_device *);
 };
 
-static const struct multi_id multi_id[] = {
-       { MANFID_OMEGA,   PRODID_OMEGA_QSP_100,         4 },
-       { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232,    2 },
-       { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232_D1, 2 },
-       { MANFID_QUATECH, PRODID_QUATECH_QUAD_RS232,    4 },
-       { MANFID_SOCKET,  PRODID_SOCKET_DUAL_RS232,     2 },
-       { MANFID_INTEL,   PRODID_INTEL_DUAL_RS232,      2 },
-       { MANFID_NATINST, PRODID_NATINST_QUAD_RS232,    4 }
-};
-#define MULTI_COUNT (sizeof(multi_id)/sizeof(struct multi_id))
-
 struct serial_info {
        struct pcmcia_device    *p_dev;
        int                     ndev;
@@ -107,6 +100,7 @@ struct serial_info {
        int                     c950ctrl;
        dev_node_t              node[4];
        int                     line[4];
+       const struct serial_quirk *quirk;
 };
 
 struct serial_cfg_mem {
@@ -115,37 +109,165 @@ struct serial_cfg_mem {
        u_char buf[256];
 };
 
+/*
+ * vers_1 5.0, "Brain Boxes", "2-Port RS232 card", "r6"
+ * manfid 0x0160, 0x0104
+ * This card appears to have a 14.7456MHz clock.
+ */
+static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port)
+{
+       port->uartclk = 14745600;
+}
 
-static int serial_config(struct pcmcia_device * link);
+static int quirk_post_ibm(struct pcmcia_device *link)
+{
+       conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
+       int last_ret, last_fn;
 
+       last_ret = pcmcia_access_configuration_register(link, &reg);
+       if (last_ret) {
+               last_fn = AccessConfigurationRegister;
+               goto cs_failed;
+       }
+       reg.Action = CS_WRITE;
+       reg.Value = reg.Value | 1;
+       last_ret = pcmcia_access_configuration_register(link, &reg);
+       if (last_ret) {
+               last_fn = AccessConfigurationRegister;
+               goto cs_failed;
+       }
+       return 0;
 
-static void wakeup_card(struct serial_info *info)
+ cs_failed:
+       cs_error(link, last_fn, last_ret);
+       return -ENODEV;
+}
+
+/*
+ * Nokia cards are not really multiport cards.  Shouldn't this
+ * be handled by setting the quirk entry .multi = 0 | 1 ?
+ */
+static void quirk_config_nokia(struct pcmcia_device *link)
 {
-       int ctrl = info->c950ctrl;
-
-       if (info->manfid == MANFID_OXSEMI) {
-               outb(12, ctrl + 1);
-       } else if (info->manfid == MANFID_POSSIO && info->prodid == PRODID_POSSIO_GCC) {
-               /* request_region? oxsemi branch does no request_region too... */
-               /* This sequence is needed to properly initialize MC45 attached to OXCF950.
-                * I tried decreasing these msleep()s, but it worked properly (survived
-                * 1000 stop/start operations) with these timeouts (or bigger). */
-               outb(0xA, ctrl + 1);
-               msleep(100);
-               outb(0xE, ctrl + 1);
-               msleep(300);
-               outb(0xC, ctrl + 1);
-               msleep(100);
-               outb(0xE, ctrl + 1);
-               msleep(200);
-               outb(0xF, ctrl + 1);
-               msleep(100);
-               outb(0xE, ctrl + 1);
-               msleep(100);
-               outb(0xC, ctrl + 1);
+       struct serial_info *info = link->priv;
+
+       if (info->multi > 1)
+               info->multi = 1;
+}
+
+static void quirk_wakeup_oxsemi(struct pcmcia_device *link)
+{
+       struct serial_info *info = link->priv;
+
+       outb(12, info->c950ctrl + 1);
+}
+
+/* request_region? oxsemi branch does no request_region too... */
+/*
+ * This sequence is needed to properly initialize MC45 attached to OXCF950.
+ * I tried decreasing these msleep()s, but it worked properly (survived
+ * 1000 stop/start operations) with these timeouts (or bigger).
+ */
+static void quirk_wakeup_possio_gcc(struct pcmcia_device *link)
+{
+       struct serial_info *info = link->priv;
+       unsigned int ctrl = info->c950ctrl;
+
+       outb(0xA, ctrl + 1);
+       msleep(100);
+       outb(0xE, ctrl + 1);
+       msleep(300);
+       outb(0xC, ctrl + 1);
+       msleep(100);
+       outb(0xE, ctrl + 1);
+       msleep(200);
+       outb(0xF, ctrl + 1);
+       msleep(100);
+       outb(0xE, ctrl + 1);
+       msleep(100);
+       outb(0xC, ctrl + 1);
+}
+
+/*
+ * Socket Dual IO: this enables irq's for second port
+ */
+static void quirk_config_socket(struct pcmcia_device *link)
+{
+       struct serial_info *info = link->priv;
+
+       if (info->multi) {
+               link->conf.Present |= PRESENT_EXT_STATUS;
+               link->conf.ExtStatus = ESR_REQ_ATTN_ENA;
        }
 }
 
+static const struct serial_quirk quirks[] = {
+       {
+               .manfid = 0x0160,
+               .prodid = 0x0104,
+               .multi  = -1,
+               .setup  = quirk_setup_brainboxes_0104,
+       }, {
+               .manfid = MANFID_IBM,
+               .prodid = ~0,
+               .multi  = -1,
+               .post   = quirk_post_ibm,
+       }, {
+               .manfid = MANFID_INTEL,
+               .prodid = PRODID_INTEL_DUAL_RS232,
+               .multi  = 2,
+       }, {
+               .manfid = MANFID_NATINST,
+               .prodid = PRODID_NATINST_QUAD_RS232,
+               .multi  = 4,
+       }, {
+               .manfid = MANFID_NOKIA,
+               .prodid = ~0,
+               .multi  = -1,
+               .config = quirk_config_nokia,
+       }, {
+               .manfid = MANFID_OMEGA,
+               .prodid = PRODID_OMEGA_QSP_100,
+               .multi  = 4,
+       }, {
+               .manfid = MANFID_OXSEMI,
+               .prodid = ~0,
+               .multi  = -1,
+               .wakeup = quirk_wakeup_oxsemi,
+       }, {
+               .manfid = MANFID_POSSIO,
+               .prodid = PRODID_POSSIO_GCC,
+               .multi  = -1,
+               .wakeup = quirk_wakeup_possio_gcc,
+       }, {
+               .manfid = MANFID_QUATECH,
+               .prodid = PRODID_QUATECH_DUAL_RS232,
+               .multi  = 2,
+       }, {
+               .manfid = MANFID_QUATECH,
+               .prodid = PRODID_QUATECH_DUAL_RS232_D1,
+               .multi  = 2,
+       }, {
+               .manfid = MANFID_QUATECH,
+               .prodid = PRODID_QUATECH_QUAD_RS232,
+               .multi  = 4,
+       }, {
+               .manfid = MANFID_SOCKET,
+               .prodid = PRODID_SOCKET_DUAL_RS232,
+               .multi  = 2,
+               .config = quirk_config_socket,
+       }, {
+               .manfid = MANFID_SOCKET,
+               .prodid = ~0,
+               .multi  = -1,
+               .config = quirk_config_socket,
+       }
+};
+
+
+static int serial_config(struct pcmcia_device * link);
+
+
 /*======================================================================
 
     After a card is removed, serial_remove() will unregister
@@ -185,14 +307,14 @@ static int serial_suspend(struct pcmcia_device *link)
 
 static int serial_resume(struct pcmcia_device *link)
 {
-       if (pcmcia_dev_present(link)) {
-               struct serial_info *info = link->priv;
-               int i;
+       struct serial_info *info = link->priv;
+       int i;
 
-               for (i = 0; i < info->ndev; i++)
-                       serial8250_resume_port(info->line[i]);
-               wakeup_card(info);
-       }
+       for (i = 0; i < info->ndev; i++)
+               serial8250_resume_port(info->line[i]);
+
+       if (info->quirk && info->quirk->wakeup)
+               info->quirk->wakeup(link);
 
        return 0;
 }
@@ -278,6 +400,10 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
        port.dev = &handle_to_dev(handle);
        if (buggy_uart)
                port.flags |= UPF_BUGGY_UART;
+
+       if (info->quirk && info->quirk->setup)
+               info->quirk->setup(handle, &port);
+
        line = serial8250_register_port(&port);
        if (line < 0) {
                printk(KERN_NOTICE "serial_cs: serial8250_register_port() at "
@@ -433,6 +559,13 @@ next_entry:
        }
        if (info->multi && (info->manfid == MANFID_3COM))
                link->conf.ConfigIndex &= ~(0x08);
+
+       /*
+        * Apply any configuration quirks.
+        */
+       if (info->quirk && info->quirk->config)
+               info->quirk->config(link);
+
        i = pcmcia_request_configuration(link, &link->conf);
        if (i != CS_SUCCESS) {
                cs_error(link, RequestConfiguration, i);
@@ -521,11 +654,13 @@ static int multi_config(struct pcmcia_device * link)
                cs_error(link, RequestIRQ, i);
                link->irq.AssignedIRQ = 0;
        }
-       /* Socket Dual IO: this enables irq's for second port */
-       if (info->multi && (info->manfid == MANFID_SOCKET)) {
-               link->conf.Present |= PRESENT_EXT_STATUS;
-               link->conf.ExtStatus = ESR_REQ_ATTN_ENA;
-       }
+
+       /*
+        * Apply any configuration quirks.
+        */
+       if (info->quirk && info->quirk->config)
+               info->quirk->config(link);
+
        i = pcmcia_request_configuration(link, &link->conf);
        if (i != CS_SUCCESS) {
                cs_error(link, RequestConfiguration, i);
@@ -550,17 +685,19 @@ static int multi_config(struct pcmcia_device * link)
                                        link->irq.AssignedIRQ);
                }
                info->c950ctrl = base2;
-               wakeup_card(info);
+
+               /*
+                * FIXME: We really should wake up the port prior to
+                * handing it over to the serial layer.
+                */
+               if (info->quirk && info->quirk->wakeup)
+                       info->quirk->wakeup(link);
+
                rc = 0;
                goto free_cfg_mem;
        }
 
        setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
-       /* The Nokia cards are not really multiport cards */
-       if (info->manfid == MANFID_NOKIA) {
-               rc = 0;
-               goto free_cfg_mem;
-       }
        for (i = 0; i < info->multi - 1; i++)
                setup_serial(link, info, base2 + (8 * i),
                                link->irq.AssignedIRQ);
@@ -622,13 +759,16 @@ static int serial_config(struct pcmcia_device * link)
        tuple->DesiredTuple = CISTPL_MANFID;
        if (first_tuple(link, tuple, parse) == CS_SUCCESS) {
                info->manfid = parse->manfid.manf;
-               info->prodid = le16_to_cpu(buf[1]);
-               for (i = 0; i < MULTI_COUNT; i++)
-                       if ((info->manfid == multi_id[i].manfid) &&
-                           (parse->manfid.card == multi_id[i].prodid))
+               info->prodid = parse->manfid.card;
+
+               for (i = 0; i < ARRAY_SIZE(quirks); i++)
+                       if ((quirks[i].manfid == ~0 ||
+                            quirks[i].manfid == info->manfid) &&
+                           (quirks[i].prodid == ~0 ||
+                            quirks[i].prodid == info->prodid)) {
+                               info->quirk = &quirks[i];
                                break;
-               if (i < MULTI_COUNT)
-                       info->multi = multi_id[i].multi;
+                       }
        }
 
        /* Another check for dual-serial cards: look for either serial or
@@ -648,6 +788,12 @@ static int serial_config(struct pcmcia_device * link)
                }
        }
 
+       /*
+        * Apply any multi-port quirk.
+        */
+       if (info->quirk && info->quirk->multi != -1)
+               info->multi = info->quirk->multi;
+
        if (info->multi > 1)
                multi_config(link);
        else
@@ -656,21 +802,13 @@ static int serial_config(struct pcmcia_device * link)
        if (info->ndev == 0)
                goto failed;
 
-       if (info->manfid == MANFID_IBM) {
-               conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
-               last_ret = pcmcia_access_configuration_register(link, &reg);
-               if (last_ret) {
-                       last_fn = AccessConfigurationRegister;
-                       goto cs_failed;
-               }
-               reg.Action = CS_WRITE;
-               reg.Value = reg.Value | 1;
-               last_ret = pcmcia_access_configuration_register(link, &reg);
-               if (last_ret) {
-                       last_fn = AccessConfigurationRegister;
-                       goto cs_failed;
-               }
-       }
+       /*
+        * Apply any post-init quirk.  FIXME: This should really happen
+        * before we register the port, since it might already be in use.
+        */
+       if (info->quirk && info->quirk->post)
+               if (info->quirk->post(link))
+                       goto failed;
 
        link->dev_node = &info->node[0];
        kfree(cfg_mem);
index b361669f85a17bf8372df6fa6417e0dbbc0fc13e..ebd8d2bb17fd24949701f4af6d4e07a0c68a00fb 100644 (file)
@@ -990,7 +990,6 @@ int __init early_serial_txx9_setup(struct uart_port *port)
 /**
  *     serial_txx9_suspend_port - suspend one serial port
  *     @line:  serial line number
- *      @level: the level of port suspension, as per uart_suspend_port
  *
  *     Suspend one serial port.
  */
@@ -1002,7 +1001,6 @@ static void serial_txx9_suspend_port(int line)
 /**
  *     serial_txx9_resume_port - resume one serial port
  *     @line:  serial line number
- *      @level: the level of port resumption, as per uart_resume_port
  *
  *     Resume one serial port.
  */
index 5e8a27620f6f339045981b5994b4138c69be073a..622881f26761263dafef90ed1dec8c611950a696 100644 (file)
@@ -1701,7 +1701,7 @@ static void __init probe_sccs(void)
        spin_unlock_irqrestore(&zs_lock, flags);
 }
 
-static struct tty_operations serial_ops = {
+static const struct tty_operations serial_ops = {
        .open = rs_open,
        .close = rs_close,
        .write = rs_write,
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 ca90326f2f5c6983ad6a6cd44f6980251ea11ca9..71288295df2f7f5113c30a25fc1d054c019319aa 100644 (file)
@@ -1120,7 +1120,7 @@ static struct usb_driver acm_driver = {
  * TTY driver structures.
  */
 
-static struct tty_operations acm_ops = {
+static const struct tty_operations acm_ops = {
        .open =                 acm_tty_open,
        .close =                acm_tty_close,
        .write =                acm_tty_write,
index a94c63bef632c5151e985073f2cf6457f30a0ad4..3f509beb88e4771906f4badd0237e8ff45b59b24 100644 (file)
@@ -65,7 +65,7 @@ DEFINE_MUTEX(usbfs_mutex);
 struct async {
        struct list_head asynclist;
        struct dev_state *ps;
-       pid_t pid;
+       struct pid *pid;
        uid_t uid, euid;
        unsigned int signr;
        unsigned int ifnum;
@@ -225,6 +225,7 @@ static struct async *alloc_async(unsigned int numisoframes)
 
 static void free_async(struct async *as)
 {
+       put_pid(as->pid);
        kfree(as->urb->transfer_buffer);
        kfree(as->urb->setup_packet);
        usb_free_urb(as->urb);
@@ -317,7 +318,7 @@ static void async_completed(struct urb *urb, struct pt_regs *regs)
                sinfo.si_errno = as->urb->status;
                sinfo.si_code = SI_ASYNCIO;
                sinfo.si_addr = as->userurb;
-               kill_proc_info_as_uid(as->signr, &sinfo, as->pid, as->uid, 
+               kill_pid_info_as_uid(as->signr, &sinfo, as->pid, as->uid,
                                      as->euid, as->secid);
        }
        snoop(&urb->dev->dev, "urb complete\n");
@@ -573,7 +574,7 @@ static int usbdev_open(struct inode *inode, struct file *file)
        INIT_LIST_HEAD(&ps->async_completed);
        init_waitqueue_head(&ps->wait);
        ps->discsignr = 0;
-       ps->disc_pid = current->pid;
+       ps->disc_pid = get_pid(task_pid(current));
        ps->disc_uid = current->uid;
        ps->disc_euid = current->euid;
        ps->disccontext = NULL;
@@ -611,6 +612,7 @@ static int usbdev_release(struct inode *inode, struct file *file)
        usb_autosuspend_device(dev, 1);
        usb_unlock_device(dev);
        usb_put_dev(dev);
+       put_pid(ps->disc_pid);
        kfree(ps);
        return 0;
 }
@@ -1063,7 +1065,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
                as->userbuffer = NULL;
        as->signr = uurb->signr;
        as->ifnum = ifnum;
-       as->pid = current->pid;
+       as->pid = get_pid(task_pid(current));
        as->uid = current->uid;
        as->euid = current->euid;
        security_task_getsecid(current, &as->secid);
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 37f9f5e7425d1b5e1a518302fa36cad686989c25..e658089f7b504d9a6ba90d42bdff3abc57b150f3 100644 (file)
@@ -318,8 +318,8 @@ static int rh_string (
 
        // id 3 == vendor description
        } else if (id == 3) {
-               snprintf (buf, sizeof buf, "%s %s %s", system_utsname.sysname,
-                       system_utsname.release, hcd->driver->description);
+               snprintf (buf, sizeof buf, "%s %s %s", init_utsname()->sysname,
+                       init_utsname()->release, hcd->driver->description);
 
        // unsupported IDs --> "protocol stall"
        } else
index 7c77c2d8d30073d3fcba0eda4c908f07f637b3e1..b5d6a79af0be3473b94e23dd73c6340e7db650ee 100644 (file)
@@ -699,7 +699,7 @@ static void usbfs_remove_device(struct usb_device *dev)
                        sinfo.si_errno = EPIPE;
                        sinfo.si_code = SI_ASYNCIO;
                        sinfo.si_addr = ds->disccontext;
-                       kill_proc_info_as_uid(ds->discsignr, &sinfo, ds->disc_pid, ds->disc_uid, ds->disc_euid, ds->secid);
+                       kill_pid_info_as_uid(ds->discsignr, &sinfo, ds->disc_pid, ds->disc_uid, ds->disc_euid, ds->secid);
                }
        }
 }
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 f69df137ec0ec91aac813342ee3a3e0e564a6fae..13322e33f9127652afd6179a5fda7d09d8dcd03e 100644 (file)
@@ -139,7 +139,7 @@ struct dev_state {
        struct list_head async_completed;
        wait_queue_head_t wait;     /* wake up if a request completed */
        unsigned int discsignr;
-       pid_t disc_pid;
+       struct pid *disc_pid;
        uid_t disc_uid, disc_euid;
        void __user *disccontext;
        unsigned long ifclaimed;
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 366dc0a9e52c291e8057970eca7b3de8644e53ce..1c17d26d03b807d24db3d05da49b2b3431ba5a9b 100644 (file)
@@ -2260,7 +2260,7 @@ eth_bind (struct usb_gadget *gadget)
                return -ENODEV;
        }
        snprintf (manufacturer, sizeof manufacturer, "%s %s/%s",
-               system_utsname.sysname, system_utsname.release,
+               init_utsname()->sysname, init_utsname()->release,
                gadget->name);
 
        /* If there's an RNDIS configuration, that's what Windows wants to
index c83d3b6c68f2121dd574ff92fd3c30a4b9670791..8b975d15538ddff6fb93e2757e7d1888be538881 100644 (file)
@@ -4001,7 +4001,7 @@ static int __init fsg_bind(struct usb_gadget *gadget)
        usb_gadget_set_selfpowered(gadget);
 
        snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
-                       system_utsname.sysname, system_utsname.release,
+                       init_utsname()->sysname, init_utsname()->release,
                        gadget->name);
 
        /* On a real device, serial[] would be loaded from permanent
index b68cecd57411b1c13b1bd5cb44037299ff75ab64..83601d4009e36dd66a82e026b2c9c482877f612a 100644 (file)
@@ -1189,7 +1189,7 @@ static int __devinit gmidi_bind(struct usb_gadget *gadget)
                strlcpy(manufacturer, iManufacturer, sizeof(manufacturer));
        } else {
                snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s",
-                       system_utsname.sysname, system_utsname.release,
+                       init_utsname()->sysname, init_utsname()->release,
                        gadget->name);
        }
        if (iProduct) {
index b893e3118e1be480e9b4d8bbd739152efd718141..208e55a667ac0d2124ece6bb49c17dbe1cf59d27 100644 (file)
@@ -271,7 +271,7 @@ static unsigned int use_acm = GS_DEFAULT_USE_ACM;
 
 
 /* tty driver struct */
-static struct tty_operations gs_tty_ops = {
+static const struct tty_operations gs_tty_ops = {
        .open =                 gs_open,
        .close =                gs_close,
        .write =                gs_write,
@@ -1434,7 +1434,7 @@ static int __init gs_bind(struct usb_gadget *gadget)
                return -ENOMEM;
 
        snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s",
-               system_utsname.sysname, system_utsname.release,
+               init_utsname()->sysname, init_utsname()->release,
                gadget->name);
 
        memset(dev, 0, sizeof(struct gs_dev));
index b7018ee487ea51fbe60ed42455410a4cb40feeaf..0f809dd684921662a0aa41a4dc99d54f90f3e2f7 100644 (file)
@@ -1242,7 +1242,7 @@ autoconf_fail:
                EP_OUT_NAME, EP_IN_NAME);
 
        snprintf (manufacturer, sizeof manufacturer, "%s %s with %s",
-               system_utsname.sysname, system_utsname.release,
+               init_utsname()->sysname, init_utsname()->release,
                gadget->name);
 
        return 0;
index a102a58fe3612c89589817dadcdd9b6c566d5cf4..21cd22640080fbce6d032354409f59dc61de32a3 100644 (file)
@@ -60,16 +60,17 @@ config HID_FF
          If unsure, say N.
 
 config HID_PID
-       bool "PID Devices (Microsoft Sidewinder Force Feedback 2)"
+       bool "PID device support"
        depends on HID_FF
        help
-         Say Y here if you have a PID-compliant joystick and wish to enable force
-         feedback for it. The Microsoft Sidewinder Force Feedback 2 is one such
-         device.
+         Say Y here if you have a PID-compliant device and wish to enable force
+         feedback for it. Microsoft Sidewinder Force Feedback 2 is one of such
+         devices.
 
 config LOGITECH_FF
        bool "Logitech WingMan *3D support"
        depends on HID_FF
+       select INPUT_FF_MEMLESS if USB_HID
        help
          Say Y here if you have one of these devices:
          - Logitech WingMan Cordless RumblePad
@@ -81,12 +82,21 @@ config LOGITECH_FF
 config THRUSTMASTER_FF
        bool "ThrustMaster FireStorm Dual Power 2 support (EXPERIMENTAL)"
        depends on HID_FF && EXPERIMENTAL
+       select INPUT_FF_MEMLESS if USB_HID
        help
          Say Y here if you have a THRUSTMASTER FireStore Dual Power 2,
          and want to enable force feedback support for it.
          Note: if you say N here, this device will still be supported, but without
          force feedback.
 
+config ZEROPLUS_FF
+       bool "Zeroplus based game controller support"
+       depends on HID_FF
+       select INPUT_FF_MEMLESS if USB_HID
+       help
+         Say Y here if you have a Zeroplus based game controller and want to
+         enable force feedback for it.
+
 config USB_HIDDEV
        bool "/dev/hiddev raw HID device support"
        depends on USB_HID
index 48551be324ac61fb102a530fcd34ad0205fbed57..295f459d1079ffa4c3afe69bb38d61474f503162 100644 (file)
@@ -15,7 +15,7 @@ ifeq ($(CONFIG_USB_HIDINPUT),y)
        usbhid-objs     += hid-input.o
 endif
 ifeq ($(CONFIG_HID_PID),y)
-       usbhid-objs     += pid.o
+       usbhid-objs     += hid-pidff.o
 endif
 ifeq ($(CONFIG_LOGITECH_FF),y)
        usbhid-objs     += hid-lgff.o
@@ -23,6 +23,9 @@ endif
 ifeq ($(CONFIG_THRUSTMASTER_FF),y)
        usbhid-objs     += hid-tmff.o
 endif
+ifeq ($(CONFIG_ZEROPLUS_FF),y)
+       usbhid-objs     += hid-zpff.o
+endif
 ifeq ($(CONFIG_HID_FF),y)
        usbhid-objs     += hid-ff.o
 endif
index 81b1ea01a172e40e32790a64d6602f653b0e9171..e0fd11605b430939fc10dbfc52111f9de3745d92 100644 (file)
@@ -543,8 +543,6 @@ static void hid_free_device(struct hid_device *device)
 {
        unsigned i,j;
 
-       hid_ff_exit(device);
-
        for (i = 0; i < HID_REPORT_TYPES; i++) {
                struct hid_report_enum *report_enum = device->report_enum + i;
 
@@ -1109,7 +1107,7 @@ int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
 /*
  * Find a report field with a specified HID usage.
  */
-
+#if 0
 struct hid_field *hid_find_field_by_usage(struct hid_device *hid, __u32 wanted_usage, int type)
 {
        struct hid_report *report;
@@ -1121,6 +1119,7 @@ struct hid_field *hid_find_field_by_usage(struct hid_device *hid, __u32 wanted_u
                                return report->field[i];
        return NULL;
 }
+#endif  /*  0  */
 
 static int hid_submit_out(struct hid_device *hid)
 {
index d5c91ee67991cf9e4331ad451cca18ca8e67a2c4..a8fc46c721c50cf0a1a8485d50da96c800b3f5fe 100644 (file)
@@ -44,45 +44,38 @@ struct hid_ff_initializer {
        int (*init)(struct hid_device*);
 };
 
+/*
+ * We try pidff when no other driver is found because PID is the
+ * standards compliant way of implementing force feedback in HID.
+ * pidff_init() will quickly abort if the device doesn't appear to
+ * be a PID device
+ */
 static struct hid_ff_initializer inits[] = {
 #ifdef CONFIG_LOGITECH_FF
-       {0x46d, 0xc211, hid_lgff_init}, // Logitech Cordless rumble pad
-       {0x46d, 0xc283, hid_lgff_init}, // Logitech Wingman Force 3d
-       {0x46d, 0xc295, hid_lgff_init}, // Logitech MOMO force wheel
-       {0x46d, 0xc219, hid_lgff_init}, // Logitech Cordless rumble pad 2
-#endif
-#ifdef CONFIG_HID_PID
-       {0x45e, 0x001b, hid_pid_init},
+       { 0x46d, 0xc211, hid_lgff_init }, /* Logitech Cordless rumble pad */
+       { 0x46d, 0xc283, hid_lgff_init }, /* Logitech Wingman Force 3d */
+       { 0x46d, 0xc295, hid_lgff_init }, /* Logitech MOMO force wheel */
+       { 0x46d, 0xc219, hid_lgff_init }, /* Logitech Cordless rumble pad 2 */
 #endif
 #ifdef CONFIG_THRUSTMASTER_FF
-       {0x44f, 0xb304, hid_tmff_init},
+       { 0x44f, 0xb304, hid_tmff_init },
 #endif
-       {0, 0, NULL} /* Terminating entry */
+#ifdef CONFIG_ZEROPLUS_FF
+       { 0xc12, 0x0005, hid_zpff_init },
+       { 0xc12, 0x0030, hid_zpff_init },
+#endif
+       { 0,     0,      hid_pidff_init}  /* Matches anything */
 };
 
-static struct hid_ff_initializer *hid_get_ff_init(__u16 idVendor,
-                                                 __u16 idProduct)
-{
-       struct hid_ff_initializer *init;
-       for (init = inits;
-            init->idVendor
-            && !(init->idVendor == idVendor
-                 && init->idProduct == idProduct);
-            init++);
-
-       return init->idVendor? init : NULL;
-}
-
 int hid_ff_init(struct hid_device* hid)
 {
        struct hid_ff_initializer *init;
+       int vendor = le16_to_cpu(hid->dev->descriptor.idVendor);
+       int product = le16_to_cpu(hid->dev->descriptor.idProduct);
 
-       init = hid_get_ff_init(le16_to_cpu(hid->dev->descriptor.idVendor),
-                              le16_to_cpu(hid->dev->descriptor.idProduct));
+       for (init = inits; init->idVendor; init++)
+               if (init->idVendor == vendor && init->idProduct == product)
+                       break;
 
-       if (!init) {
-               dbg("hid_ff_init could not find initializer");
-               return -ENOSYS;
-       }
        return init->init(hid);
 }
index 7208839f2dbf24d50c15516b7d99971980f8160d..4c62afbeb430a31620ff3681d6ac303b613af187 100644 (file)
@@ -65,11 +65,9 @@ static const struct {
 #define map_rel(c)     do { usage->code = c; usage->type = EV_REL; bit = input->relbit; max = REL_MAX; } while (0)
 #define map_key(c)     do { usage->code = c; usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; } while (0)
 #define map_led(c)     do { usage->code = c; usage->type = EV_LED; bit = input->ledbit; max = LED_MAX; } while (0)
-#define map_ff(c)      do { usage->code = c; usage->type = EV_FF;  bit = input->ffbit;  max =  FF_MAX; } while (0)
 
 #define map_abs_clear(c)       do { map_abs(c); clear_bit(c, bit); } while (0)
 #define map_key_clear(c)       do { map_key(c); clear_bit(c, bit); } while (0)
-#define map_ff_effect(c)       do { set_bit(c, input->ffbit); } while (0)
 
 #ifdef CONFIG_USB_HIDINPUT_POWERBOOK
 
@@ -525,23 +523,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
 
                case HID_UP_PID:
 
-                       set_bit(EV_FF, input->evbit);
                        switch(usage->hid & HID_USAGE) {
-                               case 0x26: map_ff_effect(FF_CONSTANT);  goto ignore;
-                               case 0x27: map_ff_effect(FF_RAMP);      goto ignore;
-                               case 0x28: map_ff_effect(FF_CUSTOM);    goto ignore;
-                               case 0x30: map_ff_effect(FF_SQUARE);    map_ff_effect(FF_PERIODIC); goto ignore;
-                               case 0x31: map_ff_effect(FF_SINE);      map_ff_effect(FF_PERIODIC); goto ignore;
-                               case 0x32: map_ff_effect(FF_TRIANGLE);  map_ff_effect(FF_PERIODIC); goto ignore;
-                               case 0x33: map_ff_effect(FF_SAW_UP);    map_ff_effect(FF_PERIODIC); goto ignore;
-                               case 0x34: map_ff_effect(FF_SAW_DOWN);  map_ff_effect(FF_PERIODIC); goto ignore;
-                               case 0x40: map_ff_effect(FF_SPRING);    goto ignore;
-                               case 0x41: map_ff_effect(FF_DAMPER);    goto ignore;
-                               case 0x42: map_ff_effect(FF_INERTIA);   goto ignore;
-                               case 0x43: map_ff_effect(FF_FRICTION);  goto ignore;
-                               case 0x7e: map_ff(FF_GAIN);             break;
-                               case 0x83: input->ff_effects_max = field->value[0]; goto ignore;
-                               case 0x98: map_ff(FF_AUTOCENTER);       break;
                                case 0xa4: map_key_clear(BTN_DEAD);     break;
                                default: goto ignore;
                        }
@@ -698,8 +680,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
        }
 
        if (usage->hid == (HID_UP_PID | 0x83UL)) { /* Simultaneous Effects Max */
-               input->ff_effects_max = value;
-               dbg("Maximum Effects - %d",input->ff_effects_max);
+               dbg("Maximum Effects - %d",value);
                return;
        }
 
@@ -748,7 +729,7 @@ static int hidinput_input_event(struct input_dev *dev, unsigned int type, unsign
        int offset;
 
        if (type == EV_FF)
-               return hid_ff_event(hid, dev, type, code, value);
+               return input_ff_event(dev, type, code, value);
 
        if (type != EV_LED)
                return -1;
index f07d44357ff12fbb01eb18271d0832acbbabe672..93da222b6da8ffce8ab4d11762ab562e2d4fc2d1 100644 (file)
@@ -1,12 +1,11 @@
 /*
- * $$
- *
  * Force feedback support for hid-compliant for some of the devices from
  * Logitech, namely:
  * - WingMan Cordless RumblePad
  * - WingMan Force 3D
  *
  *  Copyright (c) 2002-2004 Johann Deneux
+ *  Copyright (c) 2006 Anssi Hannula <anssi.hannula@gmail.com>
  */
 
 /*
  */
 
 #include <linux/input.h>
-#include <linux/sched.h>
-
-//#define DEBUG
 #include <linux/usb.h>
-
-#include <linux/circ_buf.h>
-
 #include "hid.h"
-#include "fixp-arith.h"
-
-
-/* Periodicity of the update */
-#define PERIOD (HZ/10)
-
-#define RUN_AT(t) (jiffies + (t))
-
-/* Effect status */
-#define EFFECT_STARTED 0     /* Effect is going to play after some time
-                               (ff_replay.delay) */
-#define EFFECT_PLAYING 1     /* Effect is being played */
-#define EFFECT_USED    2
-
-// For lgff_device::flags
-#define DEVICE_CLOSING 0     /* The driver is being unitialised */
-
-/* Check that the current process can access an effect */
-#define CHECK_OWNERSHIP(effect) (current->pid == 0 \
-        || effect.owner == current->pid)
-
-#define LGFF_CHECK_OWNERSHIP(i, l) \
-        (i>=0 && i<LGFF_EFFECTS \
-        && test_bit(EFFECT_USED, l->effects[i].flags) \
-        && CHECK_OWNERSHIP(l->effects[i]))
-
-#define LGFF_EFFECTS 8
 
 struct device_type {
        u16 idVendor;
        u16 idProduct;
-       signed short *ff;
-};
-
-struct lgff_effect {
-       pid_t owner;
-
-       struct ff_effect effect;
-
-       unsigned long flags[1];
-       unsigned int count;          /* Number of times left to play */
-       unsigned long started_at;    /* When the effect started to play */
-};
-
-struct lgff_device {
-       struct hid_device* hid;
-
-       struct hid_report* constant;
-       struct hid_report* rumble;
-       struct hid_report* condition;
-
-       struct lgff_effect effects[LGFF_EFFECTS];
-       spinlock_t lock;             /* device-level lock. Having locks on
-                                       a per-effect basis could be nice, but
-                                       isn't really necessary */
-
-       unsigned long flags[1];      /* Contains various information about the
-                                       state of the driver for this device */
-
-       struct timer_list timer;
+       const signed short *ff;
 };
 
-/* Callbacks */
-static void hid_lgff_exit(struct hid_device* hid);
-static int hid_lgff_event(struct hid_device *hid, struct input_dev *input,
-                         unsigned int type, unsigned int code, int value);
-static int hid_lgff_flush(struct input_dev *input, struct file *file);
-static int hid_lgff_upload_effect(struct input_dev *input,
-                                 struct ff_effect *effect);
-static int hid_lgff_erase(struct input_dev *input, int id);
-
-/* Local functions */
-static void hid_lgff_input_init(struct hid_device* hid);
-static void hid_lgff_timer(unsigned long timer_data);
-static struct hid_report* hid_lgff_duplicate_report(struct hid_report*);
-static void hid_lgff_delete_report(struct hid_report*);
-
-static signed short ff_rumble[] = {
+static const signed short ff_rumble[] = {
        FF_RUMBLE,
        -1
 };
 
-static signed short ff_joystick[] = {
+static const signed short ff_joystick[] = {
        FF_CONSTANT,
        -1
 };
 
-static struct device_type devices[] = {
-       {0x046d, 0xc211, ff_rumble},
-       {0x046d, 0xc219, ff_rumble},
-       {0x046d, 0xc283, ff_joystick},
-       {0x0000, 0x0000, ff_joystick}
+static const struct device_type devices[] = {
+       { 0x046d, 0xc211, ff_rumble },
+       { 0x046d, 0xc219, ff_rumble },
+       { 0x046d, 0xc283, ff_joystick },
+       { 0x0000, 0x0000, ff_joystick }
 };
 
+static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *effect)
+{
+       struct hid_device *hid = dev->private;
+       struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+       struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
+       int x, y;
+       unsigned int left, right;
+
+#define CLAMP(x) if (x < 0) x = 0; if (x > 0xff) x = 0xff
+
+       switch (effect->type) {
+       case FF_CONSTANT:
+               x = effect->u.ramp.start_level + 0x7f;  /* 0x7f is center */
+               y = effect->u.ramp.end_level + 0x7f;
+               CLAMP(x);
+               CLAMP(y);
+               report->field[0]->value[0] = 0x51;
+               report->field[0]->value[1] = 0x08;
+               report->field[0]->value[2] = x;
+               report->field[0]->value[3] = y;
+               dbg("(x, y)=(%04x, %04x)", x, y);
+               hid_submit_report(hid, report, USB_DIR_OUT);
+               break;
+
+       case FF_RUMBLE:
+               right = effect->u.rumble.strong_magnitude;
+               left = effect->u.rumble.weak_magnitude;
+               right = right * 0xff / 0xffff;
+               left = left * 0xff / 0xffff;
+               CLAMP(left);
+               CLAMP(right);
+               report->field[0]->value[0] = 0x42;
+               report->field[0]->value[1] = 0x00;
+               report->field[0]->value[2] = left;
+               report->field[0]->value[3] = right;
+               dbg("(left, right)=(%04x, %04x)", left, right);
+               hid_submit_report(hid, report, USB_DIR_OUT);
+               break;
+       }
+       return 0;
+}
+
 int hid_lgff_init(struct hid_device* hid)
 {
-       struct lgff_device *private;
-       struct hid_report* report;
-       struct hid_field* field;
+       struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
+       struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+       struct input_dev *dev = hidinput->input;
+       struct hid_report *report;
+       struct hid_field *field;
+       int error;
+       int i, j;
 
        /* Find the report to use */
-       if (list_empty(&hid->report_enum[HID_OUTPUT_REPORT].report_list)) {
+       if (list_empty(report_list)) {
                err("No output report found");
                return -1;
        }
+
        /* Check that the report looks ok */
-       report = (struct hid_report*)hid->report_enum[HID_OUTPUT_REPORT].report_list.next;
+       report = list_entry(report_list->next, struct hid_report, list);
        if (!report) {
                err("NULL output report");
                return -1;
        }
+
        field = report->field[0];
        if (!field) {
                err("NULL field");
                return -1;
        }
 
-       private = kzalloc(sizeof(struct lgff_device), GFP_KERNEL);
-       if (!private)
-               return -1;
-       hid->ff_private = private;
-
-       /* Input init */
-       hid_lgff_input_init(hid);
-
-
-       private->constant = hid_lgff_duplicate_report(report);
-       if (!private->constant) {
-               kfree(private);
-               return -1;
-       }
-       private->constant->field[0]->value[0] = 0x51;
-       private->constant->field[0]->value[1] = 0x08;
-       private->constant->field[0]->value[2] = 0x7f;
-       private->constant->field[0]->value[3] = 0x7f;
-
-       private->rumble = hid_lgff_duplicate_report(report);
-       if (!private->rumble) {
-               hid_lgff_delete_report(private->constant);
-               kfree(private);
-               return -1;
-       }
-       private->rumble->field[0]->value[0] = 0x42;
-
-
-       private->condition = hid_lgff_duplicate_report(report);
-       if (!private->condition) {
-               hid_lgff_delete_report(private->rumble);
-               hid_lgff_delete_report(private->constant);
-               kfree(private);
-               return -1;
-       }
-
-       private->hid = hid;
-
-       spin_lock_init(&private->lock);
-       init_timer(&private->timer);
-       private->timer.data = (unsigned long)private;
-       private->timer.function = hid_lgff_timer;
-
-       /* Event and exit callbacks */
-       hid->ff_exit = hid_lgff_exit;
-       hid->ff_event = hid_lgff_event;
-
-       /* Start the update task */
-       private->timer.expires = RUN_AT(PERIOD);
-       add_timer(&private->timer);  /*TODO: only run the timer when at least
-                                      one effect is playing */
-
-       printk(KERN_INFO "Force feedback for Logitech force feedback devices by Johann Deneux <johann.deneux@it.uu.se>\n");
-
-       return 0;
-}
-
-static struct hid_report* hid_lgff_duplicate_report(struct hid_report* report)
-{
-       struct hid_report* ret;
-
-       ret = kmalloc(sizeof(struct lgff_device), GFP_KERNEL);
-       if (!ret)
-               return NULL;
-       *ret = *report;
-
-       ret->field[0] = kmalloc(sizeof(struct hid_field), GFP_KERNEL);
-       if (!ret->field[0]) {
-               kfree(ret);
-               return NULL;
-       }
-       *ret->field[0] = *report->field[0];
-
-       ret->field[0]->value = kzalloc(sizeof(s32[8]), GFP_KERNEL);
-       if (!ret->field[0]->value) {
-               kfree(ret->field[0]);
-               kfree(ret);
-               return NULL;
-       }
-
-       return ret;
-}
-
-static void hid_lgff_delete_report(struct hid_report* report)
-{
-       if (report) {
-               kfree(report->field[0]->value);
-               kfree(report->field[0]);
-               kfree(report);
-       }
-}
-
-static void hid_lgff_input_init(struct hid_device* hid)
-{
-       struct device_type* dev = devices;
-       signed short* ff;
-       u16 idVendor = le16_to_cpu(hid->dev->descriptor.idVendor);
-       u16 idProduct = le16_to_cpu(hid->dev->descriptor.idProduct);
-       struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
-       struct input_dev *input_dev = hidinput->input;
-
-       while (dev->idVendor && (idVendor != dev->idVendor || idProduct != dev->idProduct))
-               dev++;
-
-       for (ff = dev->ff; *ff >= 0; ff++)
-               set_bit(*ff, input_dev->ffbit);
-
-       input_dev->upload_effect = hid_lgff_upload_effect;
-       input_dev->flush = hid_lgff_flush;
-
-       set_bit(EV_FF, input_dev->evbit);
-       input_dev->ff_effects_max = LGFF_EFFECTS;
-}
-
-static void hid_lgff_exit(struct hid_device* hid)
-{
-       struct lgff_device *lgff = hid->ff_private;
-
-       set_bit(DEVICE_CLOSING, lgff->flags);
-       del_timer_sync(&lgff->timer);
-
-       hid_lgff_delete_report(lgff->condition);
-       hid_lgff_delete_report(lgff->rumble);
-       hid_lgff_delete_report(lgff->constant);
-
-       kfree(lgff);
-}
-
-static int hid_lgff_event(struct hid_device *hid, struct input_dev* input,
-                         unsigned int type, unsigned int code, int value)
-{
-       struct lgff_device *lgff = hid->ff_private;
-       struct lgff_effect *effect = lgff->effects + code;
-       unsigned long flags;
-
-       if (type != EV_FF)                     return -EINVAL;
-       if (!LGFF_CHECK_OWNERSHIP(code, lgff)) return -EACCES;
-       if (value < 0)                         return -EINVAL;
-
-       spin_lock_irqsave(&lgff->lock, flags);
-
-       if (value > 0) {
-               if (test_bit(EFFECT_STARTED, effect->flags)) {
-                       spin_unlock_irqrestore(&lgff->lock, flags);
-                       return -EBUSY;
-               }
-               if (test_bit(EFFECT_PLAYING, effect->flags)) {
-                       spin_unlock_irqrestore(&lgff->lock, flags);
-                       return -EBUSY;
-               }
-
-               effect->count = value;
-
-               if (effect->effect.replay.delay) {
-                       set_bit(EFFECT_STARTED, effect->flags);
-               } else {
-                       set_bit(EFFECT_PLAYING, effect->flags);
-               }
-               effect->started_at = jiffies;
-       }
-       else { /* value == 0 */
-               clear_bit(EFFECT_STARTED, effect->flags);
-               clear_bit(EFFECT_PLAYING, effect->flags);
-       }
-
-       spin_unlock_irqrestore(&lgff->lock, flags);
-
-       return 0;
-
-}
-
-/* Erase all effects this process owns */
-static int hid_lgff_flush(struct input_dev *dev, struct file *file)
-{
-       struct hid_device *hid = dev->private;
-       struct lgff_device *lgff = hid->ff_private;
-       int i;
-
-       for (i=0; i<dev->ff_effects_max; ++i) {
-
-               /*NOTE: no need to lock here. The only times EFFECT_USED is
-                 modified is when effects are uploaded or when an effect is
-                 erased. But a process cannot close its dev/input/eventX fd
-                 and perform ioctls on the same fd all at the same time */
-               if ( current->pid == lgff->effects[i].owner
-                    && test_bit(EFFECT_USED, lgff->effects[i].flags)) {
-
-                       if (hid_lgff_erase(dev, i))
-                               warn("erase effect %d failed", i);
-               }
-
-       }
-
-       return 0;
-}
-
-static int hid_lgff_erase(struct input_dev *dev, int id)
-{
-       struct hid_device *hid = dev->private;
-       struct lgff_device *lgff = hid->ff_private;
-       unsigned long flags;
-
-       if (!LGFF_CHECK_OWNERSHIP(id, lgff)) return -EACCES;
-
-       spin_lock_irqsave(&lgff->lock, flags);
-       lgff->effects[id].flags[0] = 0;
-       spin_unlock_irqrestore(&lgff->lock, flags);
-
-       return 0;
-}
-
-static int hid_lgff_upload_effect(struct input_dev* input,
-                                 struct ff_effect* effect)
-{
-       struct hid_device *hid = input->private;
-       struct lgff_device *lgff = hid->ff_private;
-       struct lgff_effect new;
-       int id;
-       unsigned long flags;
-
-       dbg("ioctl rumble");
-
-       if (!test_bit(effect->type, input->ffbit)) return -EINVAL;
-
-       spin_lock_irqsave(&lgff->lock, flags);
-
-       if (effect->id == -1) {
-               int i;
-
-               for (i=0; i<LGFF_EFFECTS && test_bit(EFFECT_USED, lgff->effects[i].flags); ++i);
-               if (i >= LGFF_EFFECTS) {
-                       spin_unlock_irqrestore(&lgff->lock, flags);
-                       return -ENOSPC;
+       for (i = 0; i < ARRAY_SIZE(devices); i++) {
+               if (dev->id.vendor == devices[i].idVendor &&
+                   dev->id.product == devices[i].idProduct) {
+                       for (j = 0; devices[i].ff[j] >= 0; j++)
+                               set_bit(devices[i].ff[j], dev->ffbit);
+                       break;
                }
-
-               effect->id = i;
-               lgff->effects[i].owner = current->pid;
-               lgff->effects[i].flags[0] = 0;
-               set_bit(EFFECT_USED, lgff->effects[i].flags);
        }
-       else if (!LGFF_CHECK_OWNERSHIP(effect->id, lgff)) {
-               spin_unlock_irqrestore(&lgff->lock, flags);
-               return -EACCES;
-       }
-
-       id = effect->id;
-       new = lgff->effects[id];
-
-       new.effect = *effect;
-
-       if (test_bit(EFFECT_STARTED, lgff->effects[id].flags)
-           || test_bit(EFFECT_STARTED, lgff->effects[id].flags)) {
-
-               /* Changing replay parameters is not allowed (for the time
-                  being) */
-               if (new.effect.replay.delay != lgff->effects[id].effect.replay.delay
-                   || new.effect.replay.length != lgff->effects[id].effect.replay.length) {
-                       spin_unlock_irqrestore(&lgff->lock, flags);
-                       return -ENOSYS;
-               }
 
-               lgff->effects[id] = new;
+       error = input_ff_create_memless(dev, NULL, hid_lgff_play);
+       if (error)
+               return error;
 
-       } else {
-               lgff->effects[id] = new;
-       }
+       printk(KERN_INFO "Force feedback for Logitech force feedback devices by Johann Deneux <johann.deneux@it.uu.se>\n");
 
-       spin_unlock_irqrestore(&lgff->lock, flags);
        return 0;
 }
-
-static void hid_lgff_timer(unsigned long timer_data)
-{
-       struct lgff_device *lgff = (struct lgff_device*)timer_data;
-       struct hid_device *hid = lgff->hid;
-       unsigned long flags;
-       int x = 0x7f, y = 0x7f;   // Coordinates of constant effects
-       unsigned int left = 0, right = 0;   // Rumbling
-       int i;
-
-       spin_lock_irqsave(&lgff->lock, flags);
-
-       for (i=0; i<LGFF_EFFECTS; ++i) {
-               struct lgff_effect* effect = lgff->effects +i;
-
-               if (test_bit(EFFECT_PLAYING, effect->flags)) {
-
-                       switch (effect->effect.type) {
-                       case FF_CONSTANT: {
-                               //TODO: handle envelopes
-                               int degrees = effect->effect.direction * 360 >> 16;
-                               x += fixp_mult(fixp_sin(degrees),
-                                              fixp_new16(effect->effect.u.constant.level));
-                               y += fixp_mult(-fixp_cos(degrees),
-                                              fixp_new16(effect->effect.u.constant.level));
-                       }       break;
-                       case FF_RUMBLE:
-                               right += effect->effect.u.rumble.strong_magnitude;
-                               left += effect->effect.u.rumble.weak_magnitude;
-                               break;
-                       };
-
-                       /* One run of the effect is finished playing */
-                       if (time_after(jiffies,
-                                       effect->started_at
-                                       + effect->effect.replay.delay*HZ/1000
-                                       + effect->effect.replay.length*HZ/1000)) {
-                               dbg("Finished playing once %d", i);
-                               if (--effect->count <= 0) {
-                                       dbg("Stopped %d", i);
-                                       clear_bit(EFFECT_PLAYING, effect->flags);
-                               }
-                               else {
-                                       dbg("Start again %d", i);
-                                       if (effect->effect.replay.length != 0) {
-                                               clear_bit(EFFECT_PLAYING, effect->flags);
-                                               set_bit(EFFECT_STARTED, effect->flags);
-                                       }
-                                       effect->started_at = jiffies;
-                               }
-                       }
-
-               } else if (test_bit(EFFECT_STARTED, lgff->effects[i].flags)) {
-                       /* Check if we should start playing the effect */
-                       if (time_after(jiffies,
-                                       lgff->effects[i].started_at
-                                       + lgff->effects[i].effect.replay.delay*HZ/1000)) {
-                               dbg("Now playing %d", i);
-                               clear_bit(EFFECT_STARTED, lgff->effects[i].flags);
-                               set_bit(EFFECT_PLAYING, lgff->effects[i].flags);
-                       }
-               }
-       }
-
-#define CLAMP(x) if (x < 0) x = 0; if (x > 0xff) x = 0xff
-
-       // Clamp values
-       CLAMP(x);
-       CLAMP(y);
-       CLAMP(left);
-       CLAMP(right);
-
-#undef CLAMP
-
-       if (x != lgff->constant->field[0]->value[2]
-           || y != lgff->constant->field[0]->value[3]) {
-               lgff->constant->field[0]->value[2] = x;
-               lgff->constant->field[0]->value[3] = y;
-               dbg("(x,y)=(%04x, %04x)", x, y);
-               hid_submit_report(hid, lgff->constant, USB_DIR_OUT);
-       }
-
-       if (left != lgff->rumble->field[0]->value[2]
-           || right != lgff->rumble->field[0]->value[3]) {
-               lgff->rumble->field[0]->value[2] = left;
-               lgff->rumble->field[0]->value[3] = right;
-               dbg("(left,right)=(%04x, %04x)", left, right);
-               hid_submit_report(hid, lgff->rumble, USB_DIR_OUT);
-       }
-
-       if (!test_bit(DEVICE_CLOSING, lgff->flags)) {
-               lgff->timer.expires = RUN_AT(PERIOD);
-               add_timer(&lgff->timer);
-       }
-
-       spin_unlock_irqrestore(&lgff->lock, flags);
-}
diff --git a/drivers/usb/input/hid-pidff.c b/drivers/usb/input/hid-pidff.c
new file mode 100644 (file)
index 0000000..5420c13
--- /dev/null
@@ -0,0 +1,1330 @@
+/*
+ *  Force feedback driver for USB HID PID compliant devices
+ *
+ *  Copyright (c) 2005, 2006 Anssi Hannula <anssi.hannula@gmail.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
+ */
+
+/* #define DEBUG */
+
+#define debug(format, arg...) pr_debug("hid-pidff: " format "\n" , ## arg)
+
+#include <linux/sched.h>
+#include <linux/input.h>
+#include <linux/usb.h>
+
+#include "hid.h"
+
+#define        PID_EFFECTS_MAX         64
+
+/* Report usage table used to put reports into an array */
+
+#define PID_SET_EFFECT         0
+#define PID_EFFECT_OPERATION   1
+#define PID_DEVICE_GAIN                2
+#define PID_POOL               3
+#define PID_BLOCK_LOAD         4
+#define PID_BLOCK_FREE         5
+#define PID_DEVICE_CONTROL     6
+#define PID_CREATE_NEW_EFFECT  7
+
+#define PID_REQUIRED_REPORTS   7
+
+#define PID_SET_ENVELOPE       8
+#define PID_SET_CONDITION      9
+#define PID_SET_PERIODIC       10
+#define PID_SET_CONSTANT       11
+#define PID_SET_RAMP           12
+static const u8 pidff_reports[] = {
+       0x21, 0x77, 0x7d, 0x7f, 0x89, 0x90, 0x96, 0xab,
+       0x5a, 0x5f, 0x6e, 0x73, 0x74
+};
+
+/* device_control is really 0x95, but 0x96 specified as it is the usage of
+the only field in that report */
+
+/* Value usage tables used to put fields and values into arrays */
+
+#define PID_EFFECT_BLOCK_INDEX 0
+
+#define PID_DURATION           1
+#define PID_GAIN               2
+#define PID_TRIGGER_BUTTON     3
+#define PID_TRIGGER_REPEAT_INT 4
+#define PID_DIRECTION_ENABLE   5
+#define PID_START_DELAY                6
+static const u8 pidff_set_effect[] = {
+       0x22, 0x50, 0x52, 0x53, 0x54, 0x56, 0xa7
+};
+
+#define PID_ATTACK_LEVEL       1
+#define PID_ATTACK_TIME                2
+#define PID_FADE_LEVEL         3
+#define PID_FADE_TIME          4
+static const u8 pidff_set_envelope[] = { 0x22, 0x5b, 0x5c, 0x5d, 0x5e };
+
+#define PID_PARAM_BLOCK_OFFSET 1
+#define PID_CP_OFFSET          2
+#define PID_POS_COEFFICIENT    3
+#define PID_NEG_COEFFICIENT    4
+#define PID_POS_SATURATION     5
+#define PID_NEG_SATURATION     6
+#define PID_DEAD_BAND          7
+static const u8 pidff_set_condition[] = {
+       0x22, 0x23, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65
+};
+
+#define PID_MAGNITUDE          1
+#define PID_OFFSET             2
+#define PID_PHASE              3
+#define PID_PERIOD             4
+static const u8 pidff_set_periodic[] = { 0x22, 0x70, 0x6f, 0x71, 0x72 };
+static const u8 pidff_set_constant[] = { 0x22, 0x70 };
+
+#define PID_RAMP_START         1
+#define PID_RAMP_END           2
+static const u8 pidff_set_ramp[] = { 0x22, 0x75, 0x76 };
+
+#define PID_RAM_POOL_AVAILABLE 1
+static const u8 pidff_block_load[] = { 0x22, 0xac };
+
+#define PID_LOOP_COUNT         1
+static const u8 pidff_effect_operation[] = { 0x22, 0x7c };
+
+static const u8 pidff_block_free[] = { 0x22 };
+
+#define PID_DEVICE_GAIN_FIELD  0
+static const u8 pidff_device_gain[] = { 0x7e };
+
+#define PID_RAM_POOL_SIZE      0
+#define PID_SIMULTANEOUS_MAX   1
+#define PID_DEVICE_MANAGED_POOL        2
+static const u8 pidff_pool[] = { 0x80, 0x83, 0xa9 };
+
+/* Special field key tables used to put special field keys into arrays */
+
+#define PID_ENABLE_ACTUATORS   0
+#define PID_RESET              1
+static const u8 pidff_device_control[] = { 0x97, 0x9a };
+
+#define PID_CONSTANT   0
+#define PID_RAMP       1
+#define PID_SQUARE     2
+#define PID_SINE       3
+#define PID_TRIANGLE   4
+#define PID_SAW_UP     5
+#define PID_SAW_DOWN   6
+#define PID_SPRING     7
+#define PID_DAMPER     8
+#define PID_INERTIA    9
+#define PID_FRICTION   10
+static const u8 pidff_effect_types[] = {
+       0x26, 0x27, 0x30, 0x31, 0x32, 0x33, 0x34,
+       0x40, 0x41, 0x42, 0x43
+};
+
+#define PID_BLOCK_LOAD_SUCCESS 0
+#define PID_BLOCK_LOAD_FULL    1
+static const u8 pidff_block_load_status[] = { 0x8c, 0x8d };
+
+#define PID_EFFECT_START       0
+#define PID_EFFECT_STOP                1
+static const u8 pidff_effect_operation_status[] = { 0x79, 0x7b };
+
+struct pidff_usage {
+       struct hid_field *field;
+       s32 *value;
+};
+
+struct pidff_device {
+       struct hid_device *hid;
+
+       struct hid_report *reports[sizeof(pidff_reports)];
+
+       struct pidff_usage set_effect[sizeof(pidff_set_effect)];
+       struct pidff_usage set_envelope[sizeof(pidff_set_envelope)];
+       struct pidff_usage set_condition[sizeof(pidff_set_condition)];
+       struct pidff_usage set_periodic[sizeof(pidff_set_periodic)];
+       struct pidff_usage set_constant[sizeof(pidff_set_constant)];
+       struct pidff_usage set_ramp[sizeof(pidff_set_ramp)];
+
+       struct pidff_usage device_gain[sizeof(pidff_device_gain)];
+       struct pidff_usage block_load[sizeof(pidff_block_load)];
+       struct pidff_usage pool[sizeof(pidff_pool)];
+       struct pidff_usage effect_operation[sizeof(pidff_effect_operation)];
+       struct pidff_usage block_free[sizeof(pidff_block_free)];
+
+       /* Special field is a field that is not composed of
+          usage<->value pairs that pidff_usage values are */
+
+       /* Special field in create_new_effect */
+       struct hid_field *create_new_effect_type;
+
+       /* Special fields in set_effect */
+       struct hid_field *set_effect_type;
+       struct hid_field *effect_direction;
+
+       /* Special field in device_control */
+       struct hid_field *device_control;
+
+       /* Special field in block_load */
+       struct hid_field *block_load_status;
+
+       /* Special field in effect_operation */
+       struct hid_field *effect_operation_status;
+
+       int control_id[sizeof(pidff_device_control)];
+       int type_id[sizeof(pidff_effect_types)];
+       int status_id[sizeof(pidff_block_load_status)];
+       int operation_id[sizeof(pidff_effect_operation_status)];
+
+       int pid_id[PID_EFFECTS_MAX];
+};
+
+/*
+ * Scale an unsigned value with range 0..max for the given field
+ */
+static int pidff_rescale(int i, int max, struct hid_field *field)
+{
+       return i * (field->logical_maximum - field->logical_minimum) / max +
+           field->logical_minimum;
+}
+
+/*
+ * Scale a signed value in range -0x8000..0x7fff for the given field
+ */
+static int pidff_rescale_signed(int i, struct hid_field *field)
+{
+       return i == 0 ? 0 : i >
+           0 ? i * field->logical_maximum / 0x7fff : i *
+           field->logical_minimum / -0x8000;
+}
+
+static void pidff_set(struct pidff_usage *usage, u16 value)
+{
+       usage->value[0] = pidff_rescale(value, 0xffff, usage->field);
+       debug("calculated from %d to %d", value, usage->value[0]);
+}
+
+static void pidff_set_signed(struct pidff_usage *usage, s16 value)
+{
+       if (usage->field->logical_minimum < 0)
+               usage->value[0] = pidff_rescale_signed(value, usage->field);
+       else {
+               if (value < 0)
+                       usage->value[0] =
+                           pidff_rescale(-value, 0x8000, usage->field);
+               else
+                       usage->value[0] =
+                           pidff_rescale(value, 0x7fff, usage->field);
+       }
+       debug("calculated from %d to %d", value, usage->value[0]);
+}
+
+/*
+ * Send envelope report to the device
+ */
+static void pidff_set_envelope_report(struct pidff_device *pidff,
+                                     struct ff_envelope *envelope)
+{
+       pidff->set_envelope[PID_EFFECT_BLOCK_INDEX].value[0] =
+           pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
+
+       pidff->set_envelope[PID_ATTACK_LEVEL].value[0] =
+           pidff_rescale(envelope->attack_level >
+                         0x7fff ? 0x7fff : envelope->attack_level, 0x7fff,
+                         pidff->set_envelope[PID_ATTACK_LEVEL].field);
+       pidff->set_envelope[PID_FADE_LEVEL].value[0] =
+           pidff_rescale(envelope->fade_level >
+                         0x7fff ? 0x7fff : envelope->fade_level, 0x7fff,
+                         pidff->set_envelope[PID_FADE_LEVEL].field);
+
+       pidff->set_envelope[PID_ATTACK_TIME].value[0] = envelope->attack_length;
+       pidff->set_envelope[PID_FADE_TIME].value[0] = envelope->fade_length;
+
+       debug("attack %u => %d", envelope->attack_level,
+             pidff->set_envelope[PID_ATTACK_LEVEL].value[0]);
+
+       hid_submit_report(pidff->hid, pidff->reports[PID_SET_ENVELOPE],
+                         USB_DIR_OUT);
+}
+
+/*
+ * Test if the new envelope differs from old one
+ */
+static int pidff_needs_set_envelope(struct ff_envelope *envelope,
+                                   struct ff_envelope *old)
+{
+       return envelope->attack_level != old->attack_level ||
+              envelope->fade_level != old->fade_level ||
+              envelope->attack_length != old->attack_length ||
+              envelope->fade_length != old->fade_length;
+}
+
+/*
+ * Send constant force report to the device
+ */
+static void pidff_set_constant_force_report(struct pidff_device *pidff,
+                                           struct ff_effect *effect)
+{
+       pidff->set_constant[PID_EFFECT_BLOCK_INDEX].value[0] =
+               pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
+       pidff_set_signed(&pidff->set_constant[PID_MAGNITUDE],
+                        effect->u.constant.level);
+
+       hid_submit_report(pidff->hid, pidff->reports[PID_SET_CONSTANT],
+                         USB_DIR_OUT);
+}
+
+/*
+ * Test if the constant parameters have changed between effects
+ */
+static int pidff_needs_set_constant(struct ff_effect *effect,
+                                   struct ff_effect *old)
+{
+       return effect->u.constant.level != old->u.constant.level;
+}
+
+/*
+ * Send set effect report to the device
+ */
+static void pidff_set_effect_report(struct pidff_device *pidff,
+                                   struct ff_effect *effect)
+{
+       pidff->set_effect[PID_EFFECT_BLOCK_INDEX].value[0] =
+               pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
+       pidff->set_effect_type->value[0] =
+               pidff->create_new_effect_type->value[0];
+       pidff->set_effect[PID_DURATION].value[0] = effect->replay.length;
+       pidff->set_effect[PID_TRIGGER_BUTTON].value[0] = effect->trigger.button;
+       pidff->set_effect[PID_TRIGGER_REPEAT_INT].value[0] =
+               effect->trigger.interval;
+       pidff->set_effect[PID_GAIN].value[0] =
+               pidff->set_effect[PID_GAIN].field->logical_maximum;
+       pidff->set_effect[PID_DIRECTION_ENABLE].value[0] = 1;
+       pidff->effect_direction->value[0] =
+               pidff_rescale(effect->direction, 0xffff,
+                               pidff->effect_direction);
+       pidff->set_effect[PID_START_DELAY].value[0] = effect->replay.delay;
+
+       hid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT],
+                         USB_DIR_OUT);
+}
+
+/*
+ * Test if the values used in set_effect have changed
+ */
+static int pidff_needs_set_effect(struct ff_effect *effect,
+                                 struct ff_effect *old)
+{
+       return effect->replay.length != old->replay.length ||
+              effect->trigger.interval != old->trigger.interval ||
+              effect->trigger.button != old->trigger.button ||
+              effect->direction != old->direction ||
+              effect->replay.delay != old->replay.delay;
+}
+
+/*
+ * Send periodic effect report to the device
+ */
+static void pidff_set_periodic_report(struct pidff_device *pidff,
+                                     struct ff_effect *effect)
+{
+       pidff->set_periodic[PID_EFFECT_BLOCK_INDEX].value[0] =
+               pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
+       pidff_set_signed(&pidff->set_periodic[PID_MAGNITUDE],
+                        effect->u.periodic.magnitude);
+       pidff_set_signed(&pidff->set_periodic[PID_OFFSET],
+                        effect->u.periodic.offset);
+       pidff_set(&pidff->set_periodic[PID_PHASE], effect->u.periodic.phase);
+       pidff->set_periodic[PID_PERIOD].value[0] = effect->u.periodic.period;
+
+       hid_submit_report(pidff->hid, pidff->reports[PID_SET_PERIODIC],
+                         USB_DIR_OUT);
+
+}
+
+/*
+ * Test if periodic effect parameters have changed
+ */
+static int pidff_needs_set_periodic(struct ff_effect *effect,
+                                   struct ff_effect *old)
+{
+       return effect->u.periodic.magnitude != old->u.periodic.magnitude ||
+              effect->u.periodic.offset != old->u.periodic.offset ||
+              effect->u.periodic.phase != old->u.periodic.phase ||
+              effect->u.periodic.period != old->u.periodic.period;
+}
+
+/*
+ * Send condition effect reports to the device
+ */
+static void pidff_set_condition_report(struct pidff_device *pidff,
+                                      struct ff_effect *effect)
+{
+       int i;
+
+       pidff->set_condition[PID_EFFECT_BLOCK_INDEX].value[0] =
+               pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
+
+       for (i = 0; i < 2; i++) {
+               pidff->set_condition[PID_PARAM_BLOCK_OFFSET].value[0] = i;
+               pidff_set_signed(&pidff->set_condition[PID_CP_OFFSET],
+                                effect->u.condition[i].center);
+               pidff_set_signed(&pidff->set_condition[PID_POS_COEFFICIENT],
+                                effect->u.condition[i].right_coeff);
+               pidff_set_signed(&pidff->set_condition[PID_NEG_COEFFICIENT],
+                                effect->u.condition[i].left_coeff);
+               pidff_set(&pidff->set_condition[PID_POS_SATURATION],
+                         effect->u.condition[i].right_saturation);
+               pidff_set(&pidff->set_condition[PID_NEG_SATURATION],
+                         effect->u.condition[i].left_saturation);
+               pidff_set(&pidff->set_condition[PID_DEAD_BAND],
+                         effect->u.condition[i].deadband);
+               hid_wait_io(pidff->hid);
+               hid_submit_report(pidff->hid, pidff->reports[PID_SET_CONDITION],
+                                 USB_DIR_OUT);
+       }
+}
+
+/*
+ * Test if condition effect parameters have changed
+ */
+static int pidff_needs_set_condition(struct ff_effect *effect,
+                                    struct ff_effect *old)
+{
+       int i;
+       int ret = 0;
+
+       for (i = 0; i < 2; i++) {
+               struct ff_condition_effect *cond = &effect->u.condition[i];
+               struct ff_condition_effect *old_cond = &old->u.condition[i];
+
+               ret |= cond->center != old_cond->center ||
+                      cond->right_coeff != old_cond->right_coeff ||
+                      cond->left_coeff != old_cond->left_coeff ||
+                      cond->right_saturation != old_cond->right_saturation ||
+                      cond->left_saturation != old_cond->left_saturation ||
+                      cond->deadband != old_cond->deadband;
+       }
+
+       return ret;
+}
+
+/*
+ * Send ramp force report to the device
+ */
+static void pidff_set_ramp_force_report(struct pidff_device *pidff,
+                                       struct ff_effect *effect)
+{
+       pidff->set_ramp[PID_EFFECT_BLOCK_INDEX].value[0] =
+               pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
+       pidff_set_signed(&pidff->set_ramp[PID_RAMP_START],
+                        effect->u.ramp.start_level);
+       pidff_set_signed(&pidff->set_ramp[PID_RAMP_END],
+                        effect->u.ramp.end_level);
+       hid_submit_report(pidff->hid, pidff->reports[PID_SET_RAMP],
+                         USB_DIR_OUT);
+}
+
+/*
+ * Test if ramp force parameters have changed
+ */
+static int pidff_needs_set_ramp(struct ff_effect *effect, struct ff_effect *old)
+{
+       return effect->u.ramp.start_level != old->u.ramp.start_level ||
+              effect->u.ramp.end_level != old->u.ramp.end_level;
+}
+
+/*
+ * Send a request for effect upload to the device
+ *
+ * Returns 0 if device reported success, -ENOSPC if the device reported memory
+ * is full. Upon unknown response the function will retry for 60 times, if
+ * still unsuccessful -EIO is returned.
+ */
+static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum)
+{
+       int j;
+
+       pidff->create_new_effect_type->value[0] = efnum;
+       hid_submit_report(pidff->hid, pidff->reports[PID_CREATE_NEW_EFFECT],
+                         USB_DIR_OUT);
+       debug("create_new_effect sent, type: %d", efnum);
+
+       pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = 0;
+       pidff->block_load_status->value[0] = 0;
+       hid_wait_io(pidff->hid);
+
+       for (j = 0; j < 60; j++) {
+               debug("pid_block_load requested");
+               hid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_LOAD],
+                                 USB_DIR_IN);
+               hid_wait_io(pidff->hid);
+               if (pidff->block_load_status->value[0] ==
+                   pidff->status_id[PID_BLOCK_LOAD_SUCCESS]) {
+                       debug("device reported free memory: %d bytes",
+                             pidff->block_load[PID_RAM_POOL_AVAILABLE].value ?
+                               pidff->block_load[PID_RAM_POOL_AVAILABLE].value[0] : -1);
+                       return 0;
+               }
+               if (pidff->block_load_status->value[0] ==
+                   pidff->status_id[PID_BLOCK_LOAD_FULL]) {
+                       debug("not enough memory free: %d bytes",
+                             pidff->block_load[PID_RAM_POOL_AVAILABLE].value ?
+                               pidff->block_load[PID_RAM_POOL_AVAILABLE].value[0] : -1);
+                       return -ENOSPC;
+               }
+       }
+       printk(KERN_ERR "hid-pidff: pid_block_load failed 60 times\n");
+       return -EIO;
+}
+
+/*
+ * Play the effect with PID id n times
+ */
+static void pidff_playback_pid(struct pidff_device *pidff, int pid_id, int n)
+{
+       pidff->effect_operation[PID_EFFECT_BLOCK_INDEX].value[0] = pid_id;
+
+       if (n == 0) {
+               pidff->effect_operation_status->value[0] =
+                       pidff->operation_id[PID_EFFECT_STOP];
+       } else {
+               pidff->effect_operation_status->value[0] =
+                       pidff->operation_id[PID_EFFECT_START];
+               pidff->effect_operation[PID_LOOP_COUNT].value[0] = n;
+       }
+
+       hid_wait_io(pidff->hid);
+       hid_submit_report(pidff->hid, pidff->reports[PID_EFFECT_OPERATION],
+                         USB_DIR_OUT);
+}
+
+/**
+ * Play the effect with effect id @effect_id for @value times
+ */
+static int pidff_playback(struct input_dev *dev, int effect_id, int value)
+{
+       struct pidff_device *pidff = dev->ff->private;
+
+       pidff_playback_pid(pidff, pidff->pid_id[effect_id], value);
+
+       return 0;
+}
+
+/*
+ * Erase effect with PID id
+ */
+static void pidff_erase_pid(struct pidff_device *pidff, int pid_id)
+{
+       pidff->block_free[PID_EFFECT_BLOCK_INDEX].value[0] = pid_id;
+       hid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_FREE],
+                         USB_DIR_OUT);
+}
+
+/*
+ * Stop and erase effect with effect_id
+ */
+static int pidff_erase_effect(struct input_dev *dev, int effect_id)
+{
+       struct pidff_device *pidff = dev->ff->private;
+       int pid_id = pidff->pid_id[effect_id];
+
+       debug("starting to erase %d/%d", effect_id, pidff->pid_id[effect_id]);
+       pidff_playback_pid(pidff, pid_id, 0);
+       pidff_erase_pid(pidff, pid_id);
+
+       return 0;
+}
+
+/*
+ * Effect upload handler
+ */
+static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *effect,
+                              struct ff_effect *old)
+{
+       struct pidff_device *pidff = dev->ff->private;
+       int type_id;
+       int error;
+
+       switch (effect->type) {
+       case FF_CONSTANT:
+               if (!old) {
+                       error = pidff_request_effect_upload(pidff,
+                                       pidff->type_id[PID_CONSTANT]);
+                       if (error)
+                               return error;
+               }
+               if (!old || pidff_needs_set_effect(effect, old))
+                       pidff_set_effect_report(pidff, effect);
+               if (!old || pidff_needs_set_constant(effect, old))
+                       pidff_set_constant_force_report(pidff, effect);
+               if (!old ||
+                   pidff_needs_set_envelope(&effect->u.constant.envelope,
+                                       &old->u.constant.envelope))
+                       pidff_set_envelope_report(pidff,
+                                       &effect->u.constant.envelope);
+               break;
+
+       case FF_PERIODIC:
+               if (!old) {
+                       switch (effect->u.periodic.waveform) {
+                       case FF_SQUARE:
+                               type_id = PID_SQUARE;
+                               break;
+                       case FF_TRIANGLE:
+                               type_id = PID_TRIANGLE;
+                               break;
+                       case FF_SINE:
+                               type_id = PID_SINE;
+                               break;
+                       case FF_SAW_UP:
+                               type_id = PID_SAW_UP;
+                               break;
+                       case FF_SAW_DOWN:
+                               type_id = PID_SAW_DOWN;
+                               break;
+                       default:
+                               printk(KERN_ERR
+                                      "hid-pidff: invalid waveform\n");
+                               return -EINVAL;
+                       }
+
+                       error = pidff_request_effect_upload(pidff,
+                                       pidff->type_id[type_id]);
+                       if (error)
+                               return error;
+               }
+               if (!old || pidff_needs_set_effect(effect, old))
+                       pidff_set_effect_report(pidff, effect);
+               if (!old || pidff_needs_set_periodic(effect, old))
+                       pidff_set_periodic_report(pidff, effect);
+               if (!old ||
+                   pidff_needs_set_envelope(&effect->u.periodic.envelope,
+                                       &old->u.periodic.envelope))
+                       pidff_set_envelope_report(pidff,
+                                       &effect->u.periodic.envelope);
+               break;
+
+       case FF_RAMP:
+               if (!old) {
+                       error = pidff_request_effect_upload(pidff,
+                                       pidff->type_id[PID_RAMP]);
+                       if (error)
+                               return error;
+               }
+               if (!old || pidff_needs_set_effect(effect, old))
+                       pidff_set_effect_report(pidff, effect);
+               if (!old || pidff_needs_set_ramp(effect, old))
+                       pidff_set_ramp_force_report(pidff, effect);
+               if (!old ||
+                   pidff_needs_set_envelope(&effect->u.ramp.envelope,
+                                       &old->u.ramp.envelope))
+                       pidff_set_envelope_report(pidff,
+                                       &effect->u.ramp.envelope);
+               break;
+
+       case FF_SPRING:
+               if (!old) {
+                       error = pidff_request_effect_upload(pidff,
+                                       pidff->type_id[PID_SPRING]);
+                       if (error)
+                               return error;
+               }
+               if (!old || pidff_needs_set_effect(effect, old))
+                       pidff_set_effect_report(pidff, effect);
+               if (!old || pidff_needs_set_condition(effect, old))
+                       pidff_set_condition_report(pidff, effect);
+               break;
+
+       case FF_FRICTION:
+               if (!old) {
+                       error = pidff_request_effect_upload(pidff,
+                                       pidff->type_id[PID_FRICTION]);
+                       if (error)
+                               return error;
+               }
+               if (!old || pidff_needs_set_effect(effect, old))
+                       pidff_set_effect_report(pidff, effect);
+               if (!old || pidff_needs_set_condition(effect, old))
+                       pidff_set_condition_report(pidff, effect);
+               break;
+
+       case FF_DAMPER:
+               if (!old) {
+                       error = pidff_request_effect_upload(pidff,
+                                       pidff->type_id[PID_DAMPER]);
+                       if (error)
+                               return error;
+               }
+               if (!old || pidff_needs_set_effect(effect, old))
+                       pidff_set_effect_report(pidff, effect);
+               if (!old || pidff_needs_set_condition(effect, old))
+                       pidff_set_condition_report(pidff, effect);
+               break;
+
+       case FF_INERTIA:
+               if (!old) {
+                       error = pidff_request_effect_upload(pidff,
+                                       pidff->type_id[PID_INERTIA]);
+                       if (error)
+                               return error;
+               }
+               if (!old || pidff_needs_set_effect(effect, old))
+                       pidff_set_effect_report(pidff, effect);
+               if (!old || pidff_needs_set_condition(effect, old))
+                       pidff_set_condition_report(pidff, effect);
+               break;
+
+       default:
+               printk(KERN_ERR "hid-pidff: invalid type\n");
+               return -EINVAL;
+       }
+
+       if (!old)
+               pidff->pid_id[effect->id] =
+                   pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
+
+       debug("uploaded");
+
+       return 0;
+}
+
+/*
+ * set_gain() handler
+ */
+static void pidff_set_gain(struct input_dev *dev, u16 gain)
+{
+       struct pidff_device *pidff = dev->ff->private;
+
+       pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], gain);
+       hid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN],
+                         USB_DIR_OUT);
+}
+
+static void pidff_autocenter(struct pidff_device *pidff, u16 magnitude)
+{
+       struct hid_field *field =
+               pidff->block_load[PID_EFFECT_BLOCK_INDEX].field;
+
+       if (!magnitude) {
+               pidff_playback_pid(pidff, field->logical_minimum, 0);
+               return;
+       }
+
+       pidff_playback_pid(pidff, field->logical_minimum, 1);
+
+       pidff->set_effect[PID_EFFECT_BLOCK_INDEX].value[0] =
+               pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_minimum;
+       pidff->set_effect_type->value[0] = pidff->type_id[PID_SPRING];
+       pidff->set_effect[PID_DURATION].value[0] = 0;
+       pidff->set_effect[PID_TRIGGER_BUTTON].value[0] = 0;
+       pidff->set_effect[PID_TRIGGER_REPEAT_INT].value[0] = 0;
+       pidff_set(&pidff->set_effect[PID_GAIN], magnitude);
+       pidff->set_effect[PID_START_DELAY].value[0] = 0;
+
+       hid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT],
+                         USB_DIR_OUT);
+}
+
+/*
+ * pidff_set_autocenter() handler
+ */
+static void pidff_set_autocenter(struct input_dev *dev, u16 magnitude)
+{
+       struct pidff_device *pidff = dev->ff->private;
+
+       pidff_autocenter(pidff, magnitude);
+}
+
+/*
+ * Find fields from a report and fill a pidff_usage
+ */
+static int pidff_find_fields(struct pidff_usage *usage, const u8 *table,
+                            struct hid_report *report, int count, int strict)
+{
+       int i, j, k, found;
+
+       for (k = 0; k < count; k++) {
+               found = 0;
+               for (i = 0; i < report->maxfield; i++) {
+                       if (report->field[i]->maxusage !=
+                           report->field[i]->report_count) {
+                               debug("maxusage and report_count do not match, "
+                                     "skipping");
+                               continue;
+                       }
+                       for (j = 0; j < report->field[i]->maxusage; j++) {
+                               if (report->field[i]->usage[j].hid ==
+                                   (HID_UP_PID | table[k])) {
+                                       debug("found %d at %d->%d", k, i, j);
+                                       usage[k].field = report->field[i];
+                                       usage[k].value =
+                                               &report->field[i]->value[j];
+                                       found = 1;
+                                       break;
+                               }
+                       }
+                       if (found)
+                               break;
+               }
+               if (!found && strict) {
+                       debug("failed to locate %d", k);
+                       return -1;
+               }
+       }
+       return 0;
+}
+
+/*
+ * Return index into pidff_reports for the given usage
+ */
+static int pidff_check_usage(int usage)
+{
+       int i;
+
+       for (i = 0; i < sizeof(pidff_reports); i++)
+               if (usage == (HID_UP_PID | pidff_reports[i]))
+                       return i;
+
+       return -1;
+}
+
+/*
+ * Find the reports and fill pidff->reports[]
+ * report_type specifies either OUTPUT or FEATURE reports
+ */
+static void pidff_find_reports(struct hid_device *hid, int report_type,
+                              struct pidff_device *pidff)
+{
+       struct hid_report *report;
+       int i, ret;
+
+       list_for_each_entry(report,
+                           &hid->report_enum[report_type].report_list, list) {
+               if (report->maxfield < 1)
+                       continue;
+               ret = pidff_check_usage(report->field[0]->logical);
+               if (ret != -1) {
+                       debug("found usage 0x%02x from field->logical",
+                             pidff_reports[ret]);
+                       pidff->reports[ret] = report;
+                       continue;
+               }
+
+               /*
+                * Sometimes logical collections are stacked to indicate
+                * different usages for the report and the field, in which
+                * case we want the usage of the parent. However, Linux HID
+                * implementation hides this fact, so we have to dig it up
+                * ourselves
+                */
+               i = report->field[0]->usage[0].collection_index;
+               if (i <= 0 ||
+                   hid->collection[i - 1].type != HID_COLLECTION_LOGICAL)
+                       continue;
+               ret = pidff_check_usage(hid->collection[i - 1].usage);
+               if (ret != -1 && !pidff->reports[ret]) {
+                       debug("found usage 0x%02x from collection array",
+                             pidff_reports[ret]);
+                       pidff->reports[ret] = report;
+               }
+       }
+}
+
+/*
+ * Test if the required reports have been found
+ */
+static int pidff_reports_ok(struct pidff_device *pidff)
+{
+       int i;
+
+       for (i = 0; i <= PID_REQUIRED_REPORTS; i++) {
+               if (!pidff->reports[i]) {
+                       debug("%d missing", i);
+                       return 0;
+               }
+       }
+
+       return 1;
+}
+
+/*
+ * Find a field with a specific usage within a report
+ */
+static struct hid_field *pidff_find_special_field(struct hid_report *report,
+                                                 int usage, int enforce_min)
+{
+       int i;
+
+       for (i = 0; i < report->maxfield; i++) {
+               if (report->field[i]->logical == (HID_UP_PID | usage) &&
+                   report->field[i]->report_count > 0) {
+                       if (!enforce_min ||
+                           report->field[i]->logical_minimum == 1)
+                               return report->field[i];
+                       else {
+                               printk(KERN_ERR "hid-pidff: logical_minimum "
+                                       "is not 1 as it should be\n");
+                               return NULL;
+                       }
+               }
+       }
+       return NULL;
+}
+
+/*
+ * Fill a pidff->*_id struct table
+ */
+static int pidff_find_special_keys(int *keys, struct hid_field *fld,
+                                  const u8 *usagetable, int count)
+{
+
+       int i, j;
+       int found = 0;
+
+       for (i = 0; i < count; i++) {
+               for (j = 0; j < fld->maxusage; j++) {
+                       if (fld->usage[j].hid == (HID_UP_PID | usagetable[i])) {
+                               keys[i] = j + 1;
+                               found++;
+                               break;
+                       }
+               }
+       }
+       return found;
+}
+
+#define PIDFF_FIND_SPECIAL_KEYS(keys, field, name) \
+       pidff_find_special_keys(pidff->keys, pidff->field, pidff_ ## name, \
+               sizeof(pidff_ ## name))
+
+/*
+ * Find and check the special fields
+ */
+static int pidff_find_special_fields(struct pidff_device *pidff)
+{
+       debug("finding special fields");
+
+       pidff->create_new_effect_type =
+               pidff_find_special_field(pidff->reports[PID_CREATE_NEW_EFFECT],
+                                        0x25, 1);
+       pidff->set_effect_type =
+               pidff_find_special_field(pidff->reports[PID_SET_EFFECT],
+                                        0x25, 1);
+       pidff->effect_direction =
+               pidff_find_special_field(pidff->reports[PID_SET_EFFECT],
+                                        0x57, 0);
+       pidff->device_control =
+               pidff_find_special_field(pidff->reports[PID_DEVICE_CONTROL],
+                                        0x96, 1);
+       pidff->block_load_status =
+               pidff_find_special_field(pidff->reports[PID_BLOCK_LOAD],
+                                        0x8b, 1);
+       pidff->effect_operation_status =
+               pidff_find_special_field(pidff->reports[PID_EFFECT_OPERATION],
+                                        0x78, 1);
+
+       debug("search done");
+
+       if (!pidff->create_new_effect_type || !pidff->set_effect_type) {
+               printk(KERN_ERR "hid-pidff: effect lists not found\n");
+               return -1;
+       }
+
+       if (!pidff->effect_direction) {
+               printk(KERN_ERR "hid-pidff: direction field not found\n");
+               return -1;
+       }
+
+       if (!pidff->device_control) {
+               printk(KERN_ERR "hid-pidff: device control field not found\n");
+               return -1;
+       }
+
+       if (!pidff->block_load_status) {
+               printk(KERN_ERR
+                      "hid-pidff: block load status field not found\n");
+               return -1;
+       }
+
+       if (!pidff->effect_operation_status) {
+               printk(KERN_ERR
+                      "hid-pidff: effect operation field not found\n");
+               return -1;
+       }
+
+       pidff_find_special_keys(pidff->control_id, pidff->device_control,
+                               pidff_device_control,
+                               sizeof(pidff_device_control));
+
+       PIDFF_FIND_SPECIAL_KEYS(control_id, device_control, device_control);
+
+       if (!PIDFF_FIND_SPECIAL_KEYS(type_id, create_new_effect_type,
+                                    effect_types)) {
+               printk(KERN_ERR "hid-pidff: no effect types found\n");
+               return -1;
+       }
+
+       if (PIDFF_FIND_SPECIAL_KEYS(status_id, block_load_status,
+                                   block_load_status) !=
+                       sizeof(pidff_block_load_status)) {
+               printk(KERN_ERR
+                      "hidpidff: block load status identifiers not found\n");
+               return -1;
+       }
+
+       if (PIDFF_FIND_SPECIAL_KEYS(operation_id, effect_operation_status,
+                                   effect_operation_status) !=
+                       sizeof(pidff_effect_operation_status)) {
+               printk(KERN_ERR
+                      "hidpidff: effect operation identifiers not found\n");
+               return -1;
+       }
+
+       return 0;
+}
+
+/**
+ * Find the implemented effect types
+ */
+static int pidff_find_effects(struct pidff_device *pidff,
+                             struct input_dev *dev)
+{
+       int i;
+
+       for (i = 0; i < sizeof(pidff_effect_types); i++) {
+               int pidff_type = pidff->type_id[i];
+               if (pidff->set_effect_type->usage[pidff_type].hid !=
+                   pidff->create_new_effect_type->usage[pidff_type].hid) {
+                       printk(KERN_ERR "hid-pidff: "
+                              "effect type number %d is invalid\n", i);
+                       return -1;
+               }
+       }
+
+       if (pidff->type_id[PID_CONSTANT])
+               set_bit(FF_CONSTANT, dev->ffbit);
+       if (pidff->type_id[PID_RAMP])
+               set_bit(FF_RAMP, dev->ffbit);
+       if (pidff->type_id[PID_SQUARE]) {
+               set_bit(FF_SQUARE, dev->ffbit);
+               set_bit(FF_PERIODIC, dev->ffbit);
+       }
+       if (pidff->type_id[PID_SINE]) {
+               set_bit(FF_SINE, dev->ffbit);
+               set_bit(FF_PERIODIC, dev->ffbit);
+       }
+       if (pidff->type_id[PID_TRIANGLE]) {
+               set_bit(FF_TRIANGLE, dev->ffbit);
+               set_bit(FF_PERIODIC, dev->ffbit);
+       }
+       if (pidff->type_id[PID_SAW_UP]) {
+               set_bit(FF_SAW_UP, dev->ffbit);
+               set_bit(FF_PERIODIC, dev->ffbit);
+       }
+       if (pidff->type_id[PID_SAW_DOWN]) {
+               set_bit(FF_SAW_DOWN, dev->ffbit);
+               set_bit(FF_PERIODIC, dev->ffbit);
+       }
+       if (pidff->type_id[PID_SPRING])
+               set_bit(FF_SPRING, dev->ffbit);
+       if (pidff->type_id[PID_DAMPER])
+               set_bit(FF_DAMPER, dev->ffbit);
+       if (pidff->type_id[PID_INERTIA])
+               set_bit(FF_INERTIA, dev->ffbit);
+       if (pidff->type_id[PID_FRICTION])
+               set_bit(FF_FRICTION, dev->ffbit);
+
+       return 0;
+
+}
+
+#define PIDFF_FIND_FIELDS(name, report, strict) \
+       pidff_find_fields(pidff->name, pidff_ ## name, \
+               pidff->reports[report], \
+               sizeof(pidff_ ## name), strict)
+
+/*
+ * Fill and check the pidff_usages
+ */
+static int pidff_init_fields(struct pidff_device *pidff, struct input_dev *dev)
+{
+       int envelope_ok = 0;
+
+       if (PIDFF_FIND_FIELDS(set_effect, PID_SET_EFFECT, 1)) {
+               printk(KERN_ERR
+                      "hid-pidff: unknown set_effect report layout\n");
+               return -ENODEV;
+       }
+
+       PIDFF_FIND_FIELDS(block_load, PID_BLOCK_LOAD, 0);
+       if (!pidff->block_load[PID_EFFECT_BLOCK_INDEX].value) {
+               printk(KERN_ERR
+                      "hid-pidff: unknown pid_block_load report layout\n");
+               return -ENODEV;
+       }
+
+       if (PIDFF_FIND_FIELDS(effect_operation, PID_EFFECT_OPERATION, 1)) {
+               printk(KERN_ERR
+                      "hid-pidff: unknown effect_operation report layout\n");
+               return -ENODEV;
+       }
+
+       if (PIDFF_FIND_FIELDS(block_free, PID_BLOCK_FREE, 1)) {
+               printk(KERN_ERR
+                      "hid-pidff: unknown pid_block_free report layout\n");
+               return -ENODEV;
+       }
+
+       if (!PIDFF_FIND_FIELDS(set_envelope, PID_SET_ENVELOPE, 1))
+               envelope_ok = 1;
+
+       if (pidff_find_special_fields(pidff) || pidff_find_effects(pidff, dev))
+               return -ENODEV;
+
+       if (!envelope_ok) {
+               if (test_and_clear_bit(FF_CONSTANT, dev->ffbit))
+                       printk(KERN_WARNING "hid-pidff: "
+                              "has constant effect but no envelope\n");
+               if (test_and_clear_bit(FF_RAMP, dev->ffbit))
+                       printk(KERN_WARNING "hid-pidff: "
+                               "has ramp effect but no envelope\n");
+
+               if (test_and_clear_bit(FF_PERIODIC, dev->ffbit))
+                       printk(KERN_WARNING "hid-pidff: "
+                               "has periodic effect but no envelope\n");
+       }
+
+       if (test_bit(FF_CONSTANT, dev->ffbit) &&
+           PIDFF_FIND_FIELDS(set_constant, PID_SET_CONSTANT, 1)) {
+               printk(KERN_WARNING
+                      "hid-pidff: unknown constant effect layout\n");
+               clear_bit(FF_CONSTANT, dev->ffbit);
+       }
+
+       if (test_bit(FF_RAMP, dev->ffbit) &&
+           PIDFF_FIND_FIELDS(set_ramp, PID_SET_RAMP, 1)) {
+               printk(KERN_WARNING "hid-pidff: unknown ramp effect layout\n");
+               clear_bit(FF_RAMP, dev->ffbit);
+       }
+
+       if ((test_bit(FF_SPRING, dev->ffbit) ||
+            test_bit(FF_DAMPER, dev->ffbit) ||
+            test_bit(FF_FRICTION, dev->ffbit) ||
+            test_bit(FF_INERTIA, dev->ffbit)) &&
+           PIDFF_FIND_FIELDS(set_condition, PID_SET_CONDITION, 1)) {
+               printk(KERN_WARNING
+                      "hid-pidff: unknown condition effect layout\n");
+               clear_bit(FF_SPRING, dev->ffbit);
+               clear_bit(FF_DAMPER, dev->ffbit);
+               clear_bit(FF_FRICTION, dev->ffbit);
+               clear_bit(FF_INERTIA, dev->ffbit);
+       }
+
+       if (test_bit(FF_PERIODIC, dev->ffbit) &&
+           PIDFF_FIND_FIELDS(set_periodic, PID_SET_PERIODIC, 1)) {
+               printk(KERN_WARNING
+                      "hid-pidff: unknown periodic effect layout\n");
+               clear_bit(FF_PERIODIC, dev->ffbit);
+       }
+
+       PIDFF_FIND_FIELDS(pool, PID_POOL, 0);
+
+       if (!PIDFF_FIND_FIELDS(device_gain, PID_DEVICE_GAIN, 1))
+               set_bit(FF_GAIN, dev->ffbit);
+
+       return 0;
+}
+
+/*
+ * Reset the device
+ */
+static void pidff_reset(struct pidff_device *pidff)
+{
+       struct hid_device *hid = pidff->hid;
+       int i = 0;
+
+       pidff->device_control->value[0] = pidff->control_id[PID_RESET];
+       /* We reset twice as sometimes hid_wait_io isn't waiting long enough */
+       hid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT);
+       hid_wait_io(hid);
+       hid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT);
+       hid_wait_io(hid);
+
+       pidff->device_control->value[0] =
+               pidff->control_id[PID_ENABLE_ACTUATORS];
+       hid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT);
+       hid_wait_io(hid);
+
+       /* pool report is sometimes messed up, refetch it */
+       hid_submit_report(hid, pidff->reports[PID_POOL], USB_DIR_IN);
+       hid_wait_io(hid);
+
+       if (pidff->pool[PID_SIMULTANEOUS_MAX].value) {
+               int sim_effects = pidff->pool[PID_SIMULTANEOUS_MAX].value[0];
+               while (sim_effects < 2) {
+                       if (i++ > 20) {
+                               printk(KERN_WARNING "hid-pidff: device reports "
+                                      "%d simultaneous effects\n",
+                                      sim_effects);
+                               break;
+                       }
+                       debug("pid_pool requested again");
+                       hid_submit_report(hid, pidff->reports[PID_POOL],
+                                         USB_DIR_IN);
+                       hid_wait_io(hid);
+               }
+       }
+}
+
+/*
+ * Test if autocenter modification is using the supported method
+ */
+static int pidff_check_autocenter(struct pidff_device *pidff,
+                                 struct input_dev *dev)
+{
+       int error;
+
+       /*
+        * Let's find out if autocenter modification is supported
+        * Specification doesn't specify anything, so we request an
+        * effect upload and cancel it immediately. If the approved
+        * effect id was one above the minimum, then we assume the first
+        * effect id is a built-in spring type effect used for autocenter
+        */
+
+       error = pidff_request_effect_upload(pidff, 1);
+       if (error) {
+               printk(KERN_ERR "hid-pidff: upload request failed\n");
+               return error;
+       }
+
+       if (pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] ==
+           pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_minimum + 1) {
+               pidff_autocenter(pidff, 0xffff);
+               set_bit(FF_AUTOCENTER, dev->ffbit);
+       } else {
+               printk(KERN_NOTICE "hid-pidff: "
+                      "device has unknown autocenter control method\n");
+       }
+
+       pidff_erase_pid(pidff,
+                       pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0]);
+
+       return 0;
+
+}
+
+/*
+ * Check if the device is PID and initialize it
+ */
+int hid_pidff_init(struct hid_device *hid)
+{
+       struct pidff_device *pidff;
+       struct hid_input *hidinput = list_entry(hid->inputs.next,
+                                               struct hid_input, list);
+       struct input_dev *dev = hidinput->input;
+       struct ff_device *ff;
+       int max_effects;
+       int error;
+
+       debug("starting pid init");
+
+       if (list_empty(&hid->report_enum[HID_OUTPUT_REPORT].report_list)) {
+               debug("not a PID device, no output report");
+               return -ENODEV;
+       }
+
+       pidff = kzalloc(sizeof(*pidff), GFP_KERNEL);
+       if (!pidff)
+               return -ENOMEM;
+
+       pidff->hid = hid;
+
+       pidff_find_reports(hid, HID_OUTPUT_REPORT, pidff);
+       pidff_find_reports(hid, HID_FEATURE_REPORT, pidff);
+
+       if (!pidff_reports_ok(pidff)) {
+               debug("reports not ok, aborting");
+               error = -ENODEV;
+               goto fail;
+       }
+
+       error = pidff_init_fields(pidff, dev);
+       if (error)
+               goto fail;
+
+       pidff_reset(pidff);
+
+       if (test_bit(FF_GAIN, dev->ffbit)) {
+               pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], 0xffff);
+               hid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN],
+                                 USB_DIR_OUT);
+       }
+
+       error = pidff_check_autocenter(pidff, dev);
+       if (error)
+               goto fail;
+
+       max_effects =
+           pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_maximum -
+           pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_minimum +
+           1;
+       debug("max effects is %d", max_effects);
+
+       if (max_effects > PID_EFFECTS_MAX)
+               max_effects = PID_EFFECTS_MAX;
+
+       if (pidff->pool[PID_SIMULTANEOUS_MAX].value)
+               debug("max simultaneous effects is %d",
+                     pidff->pool[PID_SIMULTANEOUS_MAX].value[0]);
+
+       if (pidff->pool[PID_RAM_POOL_SIZE].value)
+               debug("device memory size is %d bytes",
+                     pidff->pool[PID_RAM_POOL_SIZE].value[0]);
+
+       if (pidff->pool[PID_DEVICE_MANAGED_POOL].value &&
+           pidff->pool[PID_DEVICE_MANAGED_POOL].value[0] == 0) {
+               printk(KERN_NOTICE "hid-pidff: "
+                      "device does not support device managed pool\n");
+               goto fail;
+       }
+
+       error = input_ff_create(dev, max_effects);
+       if (error)
+               goto fail;
+
+       ff = dev->ff;
+       ff->private = pidff;
+       ff->upload = pidff_upload_effect;
+       ff->erase = pidff_erase_effect;
+       ff->set_gain = pidff_set_gain;
+       ff->set_autocenter = pidff_set_autocenter;
+       ff->playback = pidff_playback;
+
+       printk(KERN_INFO "Force feedback for USB HID PID devices by "
+              "Anssi Hannula <anssi.hannula@gmail.com>\n");
+
+       return 0;
+
+ fail:
+       kfree(pidff);
+       return error;
+}
index 534425c69c0a502b1a7f86be0811446147c0afd7..2d5be4c318ac2a566e99e89865391a2140a7b2eb 100644 (file)
  */
 
 #include <linux/input.h>
-#include <linux/sched.h>
 
 #undef DEBUG
 #include <linux/usb.h>
 
-#include <linux/circ_buf.h>
-
 #include "hid.h"
-#include "fixp-arith.h"
 
 /* Usages for thrustmaster devices I know about */
 #define THRUSTMASTER_USAGE_RUMBLE_LR   (HID_UP_GENDESK | 0xbb)
-#define DELAY_CALC(t,delay)            ((t) + (delay)*HZ/1000)
-
-/* Effect status */
-#define EFFECT_STARTED 0       /* Effect is going to play after some time */
-#define EFFECT_PLAYING 1       /* Effect is playing */
-#define EFFECT_USED    2
-
-/* For tmff_device::flags */
-#define DEVICE_CLOSING 0       /* The driver is being unitialised */
-
-/* Check that the current process can access an effect */
-#define CHECK_OWNERSHIP(effect) (current->pid == 0 \
-        || effect.owner == current->pid)
-
-#define TMFF_CHECK_ID(id)      ((id) >= 0 && (id) < TMFF_EFFECTS)
 
-#define TMFF_CHECK_OWNERSHIP(i, l) \
-        (test_bit(EFFECT_USED, l->effects[i].flags) \
-        && CHECK_OWNERSHIP(l->effects[i]))
-
-#define TMFF_EFFECTS 8
-
-struct tmff_effect {
-       pid_t owner;
-
-       struct ff_effect effect;
-
-       unsigned long flags[1];
-       unsigned int count;             /* Number of times left to play */
-
-       unsigned long play_at;          /* When the effect starts to play */
-       unsigned long stop_at;          /* When the effect ends */
-};
 
 struct tmff_device {
-       struct hid_device *hid;
-
        struct hid_report *report;
-
        struct hid_field *rumble;
+};
 
-       unsigned int effects_playing;
-       struct tmff_effect effects[TMFF_EFFECTS];
-       spinlock_t lock;             /* device-level lock. Having locks on
-                                       a per-effect basis could be nice, but
-                                       isn't really necessary */
+/* Changes values from 0 to 0xffff into values from minimum to maximum */
+static inline int hid_tmff_scale(unsigned int in, int minimum, int maximum)
+{
+       int ret;
 
-       unsigned long flags[1];      /* Contains various information about the
-                                       state of the driver for this device */
+       ret = (in * (maximum - minimum) / 0xffff) + minimum;
+       if (ret < minimum)
+               return minimum;
+       if (ret > maximum)
+               return maximum;
+       return ret;
+}
 
-       struct timer_list timer;
-};
+static int hid_tmff_play(struct input_dev *dev, void *data, struct ff_effect *effect)
+{
+       struct hid_device *hid = dev->private;
+       struct tmff_device *tmff = data;
+       int left, right;        /* Rumbling */
 
-/* Callbacks */
-static void hid_tmff_exit(struct hid_device *hid);
-static int hid_tmff_event(struct hid_device *hid, struct input_dev *input,
-                         unsigned int type, unsigned int code, int value);
-static int hid_tmff_flush(struct input_dev *input, struct file *file);
-static int hid_tmff_upload_effect(struct input_dev *input,
-                                 struct ff_effect *effect);
-static int hid_tmff_erase(struct input_dev *input, int id);
+       left = hid_tmff_scale(effect->u.rumble.weak_magnitude,
+               tmff->rumble->logical_minimum, tmff->rumble->logical_maximum);
+       right = hid_tmff_scale(effect->u.rumble.strong_magnitude,
+               tmff->rumble->logical_minimum, tmff->rumble->logical_maximum);
 
-/* Local functions */
-static void hid_tmff_recalculate_timer(struct tmff_device *tmff);
-static void hid_tmff_timer(unsigned long timer_data);
+       tmff->rumble->value[0] = left;
+       tmff->rumble->value[1] = right;
+       dbg("(left,right)=(%08x, %08x)", left, right);
+       hid_submit_report(hid, tmff->report, USB_DIR_OUT);
+
+       return 0;
+}
 
 int hid_tmff_init(struct hid_device *hid)
 {
-       struct tmff_device *private;
+       struct tmff_device *tmff;
        struct list_head *pos;
        struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
        struct input_dev *input_dev = hidinput->input;
+       int error;
 
-       private = kzalloc(sizeof(struct tmff_device), GFP_KERNEL);
-       if (!private)
+       tmff = kzalloc(sizeof(struct tmff_device), GFP_KERNEL);
+       if (!tmff)
                return -ENOMEM;
 
-       hid->ff_private = private;
-
        /* Find the report to use */
        __list_for_each(pos, &hid->report_enum[HID_OUTPUT_REPORT].report_list) {
                struct hid_report *report = (struct hid_report *)pos;
@@ -142,18 +110,18 @@ int hid_tmff_init(struct hid_device *hid)
                                                continue;
                                        }
 
-                                       if (private->report && private->report != report) {
+                                       if (tmff->report && tmff->report != report) {
                                                warn("ignoring THRUSTMASTER_USAGE_RUMBLE_LR in other report");
                                                continue;
                                        }
 
-                                       if (private->rumble && private->rumble != field) {
+                                       if (tmff->rumble && tmff->rumble != field) {
                                                warn("ignoring duplicate THRUSTMASTER_USAGE_RUMBLE_LR");
                                                continue;
                                        }
 
-                                       private->report = report;
-                                       private->rumble = field;
+                                       tmff->report = report;
+                                       tmff->rumble = field;
 
                                        set_bit(FF_RUMBLE, input_dev->ffbit);
                                        break;
@@ -162,302 +130,17 @@ int hid_tmff_init(struct hid_device *hid)
                                        warn("ignoring unknown output usage %08x", field->usage[0].hid);
                                        continue;
                        }
-
-                       /* Fallthrough to here only when a valid usage is found */
-                       input_dev->upload_effect = hid_tmff_upload_effect;
-                       input_dev->flush = hid_tmff_flush;
-
-                       set_bit(EV_FF, input_dev->evbit);
-                       input_dev->ff_effects_max = TMFF_EFFECTS;
                }
        }
 
-       private->hid = hid;
-
-       spin_lock_init(&private->lock);
-       init_timer(&private->timer);
-       private->timer.data = (unsigned long)private;
-       private->timer.function = hid_tmff_timer;
-
-       /* Event and exit callbacks */
-       hid->ff_exit = hid_tmff_exit;
-       hid->ff_event = hid_tmff_event;
-
-       info("Force feedback for ThrustMaster rumble pad devices by Zinx Verituse <zinx@epicsol.org>");
-
-       return 0;
-}
-
-static void hid_tmff_exit(struct hid_device *hid)
-{
-       struct tmff_device *tmff = hid->ff_private;
-       unsigned long flags;
-
-       spin_lock_irqsave(&tmff->lock, flags);
-
-       set_bit(DEVICE_CLOSING, tmff->flags);
-       del_timer_sync(&tmff->timer);
-
-       spin_unlock_irqrestore(&tmff->lock, flags);
-
-       kfree(tmff);
-}
-
-static int hid_tmff_event(struct hid_device *hid, struct input_dev *input,
-                         unsigned int type, unsigned int code, int value)
-{
-       struct tmff_device *tmff = hid->ff_private;
-       struct tmff_effect *effect = &tmff->effects[code];
-       unsigned long flags;
-
-       if (type != EV_FF)
-               return -EINVAL;
-       if (!TMFF_CHECK_ID(code))
-               return -EINVAL;
-       if (!TMFF_CHECK_OWNERSHIP(code, tmff))
-               return -EACCES;
-       if (value < 0)
-               return -EINVAL;
-
-       spin_lock_irqsave(&tmff->lock, flags);
-
-       if (value > 0) {
-               set_bit(EFFECT_STARTED, effect->flags);
-               clear_bit(EFFECT_PLAYING, effect->flags);
-               effect->count = value;
-               effect->play_at = DELAY_CALC(jiffies, effect->effect.replay.delay);
-       } else {
-               clear_bit(EFFECT_STARTED, effect->flags);
-               clear_bit(EFFECT_PLAYING, effect->flags);
-       }
-
-       hid_tmff_recalculate_timer(tmff);
-
-       spin_unlock_irqrestore(&tmff->lock, flags);
-
-       return 0;
-
-}
-
-/* Erase all effects this process owns */
-
-static int hid_tmff_flush(struct input_dev *dev, struct file *file)
-{
-       struct hid_device *hid = dev->private;
-       struct tmff_device *tmff = hid->ff_private;
-       int i;
-
-       for (i=0; i<dev->ff_effects_max; ++i)
-
-            /* NOTE: no need to lock here. The only times EFFECT_USED is
-               modified is when effects are uploaded or when an effect is
-               erased. But a process cannot close its dev/input/eventX fd
-               and perform ioctls on the same fd all at the same time */
-
-               if (current->pid == tmff->effects[i].owner
-                    && test_bit(EFFECT_USED, tmff->effects[i].flags))
-                       if (hid_tmff_erase(dev, i))
-                               warn("erase effect %d failed", i);
-
-
-       return 0;
-}
-
-static int hid_tmff_erase(struct input_dev *dev, int id)
-{
-       struct hid_device *hid = dev->private;
-       struct tmff_device *tmff = hid->ff_private;
-       unsigned long flags;
-
-       if (!TMFF_CHECK_ID(id))
-               return -EINVAL;
-       if (!TMFF_CHECK_OWNERSHIP(id, tmff))
-               return -EACCES;
-
-       spin_lock_irqsave(&tmff->lock, flags);
-
-       tmff->effects[id].flags[0] = 0;
-       hid_tmff_recalculate_timer(tmff);
-
-       spin_unlock_irqrestore(&tmff->lock, flags);
-
-       return 0;
-}
-
-static int hid_tmff_upload_effect(struct input_dev *input,
-                                 struct ff_effect *effect)
-{
-       struct hid_device *hid = input->private;
-       struct tmff_device *tmff = hid->ff_private;
-       int id;
-       unsigned long flags;
-
-       if (!test_bit(effect->type, input->ffbit))
-               return -EINVAL;
-       if (effect->id != -1 && !TMFF_CHECK_ID(effect->id))
-               return -EINVAL;
-
-       spin_lock_irqsave(&tmff->lock, flags);
-
-       if (effect->id == -1) {
-               /* Find a free effect */
-               for (id = 0; id < TMFF_EFFECTS && test_bit(EFFECT_USED, tmff->effects[id].flags); ++id);
-
-               if (id >= TMFF_EFFECTS) {
-                       spin_unlock_irqrestore(&tmff->lock, flags);
-                       return -ENOSPC;
-               }
-
-               effect->id = id;
-               tmff->effects[id].owner = current->pid;
-               tmff->effects[id].flags[0] = 0;
-               set_bit(EFFECT_USED, tmff->effects[id].flags);
-
-       } else {
-               /* Re-uploading an owned effect, to change parameters */
-               id = effect->id;
-               clear_bit(EFFECT_PLAYING, tmff->effects[id].flags);
+       error = input_ff_create_memless(input_dev, tmff, hid_tmff_play);
+       if (error) {
+               kfree(tmff);
+               return error;
        }
 
-       tmff->effects[id].effect = *effect;
-
-       hid_tmff_recalculate_timer(tmff);
+       info("Force feedback for ThrustMaster rumble pad devices by Zinx Verituse <zinx@epicsol.org>");
 
-       spin_unlock_irqrestore(&tmff->lock, flags);
        return 0;
 }
 
-/* Start the timer for the next start/stop/delay */
-/* Always call this while tmff->lock is locked */
-
-static void hid_tmff_recalculate_timer(struct tmff_device *tmff)
-{
-       int i;
-       int events = 0;
-       unsigned long next_time;
-
-       next_time = 0;  /* Shut up compiler's incorrect warning */
-
-       /* Find the next change in an effect's status */
-       for (i = 0; i < TMFF_EFFECTS; ++i) {
-               struct tmff_effect *effect = &tmff->effects[i];
-               unsigned long play_time;
-
-               if (!test_bit(EFFECT_STARTED, effect->flags))
-                       continue;
-
-               effect->stop_at = DELAY_CALC(effect->play_at, effect->effect.replay.length);
-
-               if (!test_bit(EFFECT_PLAYING, effect->flags))
-                       play_time = effect->play_at;
-               else
-                       play_time = effect->stop_at;
-
-               events++;
-
-               if (time_after(jiffies, play_time))
-                       play_time = jiffies;
-
-               if (events == 1)
-                       next_time = play_time;
-               else {
-                       if (time_after(next_time, play_time))
-                               next_time = play_time;
-               }
-       }
-
-       if (!events && tmff->effects_playing) {
-               /* Treat all effects turning off as an event */
-               events = 1;
-               next_time = jiffies;
-       }
-
-       if (!events) {
-               /* No events, no time, no need for a timer. */
-               del_timer_sync(&tmff->timer);
-               return;
-       }
-
-       mod_timer(&tmff->timer, next_time);
-}
-
-/* Changes values from 0 to 0xffff into values from minimum to maximum */
-static inline int hid_tmff_scale(unsigned int in, int minimum, int maximum)
-{
-       int ret;
-
-       ret = (in * (maximum - minimum) / 0xffff) + minimum;
-       if (ret < minimum)
-               return minimum;
-       if (ret > maximum)
-               return maximum;
-       return ret;
-}
-
-static void hid_tmff_timer(unsigned long timer_data)
-{
-       struct tmff_device *tmff = (struct tmff_device *) timer_data;
-       struct hid_device *hid = tmff->hid;
-       unsigned long flags;
-       int left = 0, right = 0;        /* Rumbling */
-       int i;
-
-       spin_lock_irqsave(&tmff->lock, flags);
-
-       tmff->effects_playing = 0;
-
-       for (i = 0; i < TMFF_EFFECTS; ++i) {
-               struct tmff_effect *effect = &tmff->effects[i];
-
-               if (!test_bit(EFFECT_STARTED, effect->flags))
-                       continue;
-
-               if (!time_after(jiffies, effect->play_at))
-                       continue;
-
-               if (time_after(jiffies, effect->stop_at)) {
-
-                       dbg("Finished playing once %d", i);
-                       clear_bit(EFFECT_PLAYING, effect->flags);
-
-                       if (--effect->count <= 0) {
-                               dbg("Stopped %d", i);
-                               clear_bit(EFFECT_STARTED, effect->flags);
-                               continue;
-                       } else {
-                               dbg("Start again %d", i);
-                               effect->play_at = DELAY_CALC(jiffies, effect->effect.replay.delay);
-                               continue;
-                       }
-               }
-
-               ++tmff->effects_playing;
-
-               set_bit(EFFECT_PLAYING, effect->flags);
-
-               switch (effect->effect.type) {
-                       case FF_RUMBLE:
-                               right += effect->effect.u.rumble.strong_magnitude;
-                               left += effect->effect.u.rumble.weak_magnitude;
-                               break;
-                       default:
-                               BUG();
-                               break;
-               }
-       }
-
-       left = hid_tmff_scale(left, tmff->rumble->logical_minimum, tmff->rumble->logical_maximum);
-       right = hid_tmff_scale(right, tmff->rumble->logical_minimum, tmff->rumble->logical_maximum);
-
-       if (left != tmff->rumble->value[0] || right != tmff->rumble->value[1]) {
-               tmff->rumble->value[0] = left;
-               tmff->rumble->value[1] = right;
-               dbg("(left,right)=(%08x, %08x)", left, right);
-               hid_submit_report(hid, tmff->report, USB_DIR_OUT);
-       }
-
-       if (!test_bit(DEVICE_CLOSING, tmff->flags))
-               hid_tmff_recalculate_timer(tmff);
-
-       spin_unlock_irqrestore(&tmff->lock, flags);
-}
diff --git a/drivers/usb/input/hid-zpff.c b/drivers/usb/input/hid-zpff.c
new file mode 100644 (file)
index 0000000..d2ce321
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ *  Force feedback support for Zeroplus based devices
+ *
+ *  Copyright (c) 2005, 2006 Anssi Hannula <anssi.hannula@gmail.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
+ */
+
+
+/* #define DEBUG */
+
+#define debug(format, arg...) pr_debug("hid-zpff: " format "\n" , ## arg)
+
+#include <linux/input.h>
+#include <linux/usb.h>
+#include "hid.h"
+
+struct zpff_device {
+       struct hid_report *report;
+};
+
+static int hid_zpff_play(struct input_dev *dev, void *data,
+                        struct ff_effect *effect)
+{
+       struct hid_device *hid = dev->private;
+       struct zpff_device *zpff = data;
+       int left, right;
+
+       /*
+        * The following is specified the other way around in the Zeroplus
+        * datasheet but the order below is correct for the XFX Executioner;
+        * however it is possible that the XFX Executioner is an exception
+        */
+
+       left = effect->u.rumble.strong_magnitude;
+       right = effect->u.rumble.weak_magnitude;
+       debug("called with 0x%04x 0x%04x", left, right);
+
+       left = left * 0x7f / 0xffff;
+       right = right * 0x7f / 0xffff;
+
+       zpff->report->field[2]->value[0] = left;
+       zpff->report->field[3]->value[0] = right;
+       debug("running with 0x%02x 0x%02x", left, right);
+       hid_submit_report(hid, zpff->report, USB_DIR_OUT);
+
+       return 0;
+}
+
+int hid_zpff_init(struct hid_device *hid)
+{
+       struct zpff_device *zpff;
+       struct hid_report *report;
+       struct hid_input *hidinput = list_entry(hid->inputs.next,
+                                               struct hid_input, list);
+       struct list_head *report_list =
+                       &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+       struct input_dev *dev = hidinput->input;
+       int error;
+
+       if (list_empty(report_list)) {
+               printk(KERN_ERR "hid-zpff: no output report found\n");
+               return -ENODEV;
+       }
+
+       report = list_entry(report_list->next, struct hid_report, list);
+
+       if (report->maxfield < 4) {
+               printk(KERN_ERR "hid-zpff: not enough fields in report\n");
+               return -ENODEV;
+       }
+
+       zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL);
+       if (!zpff)
+               return -ENOMEM;
+
+       set_bit(FF_RUMBLE, dev->ffbit);
+
+       error = input_ff_create_memless(dev, zpff, hid_zpff_play);
+       if (error) {
+               kfree(zpff);
+               return error;
+       }
+
+       zpff->report = report;
+       zpff->report->field[0]->value[0] = 0x00;
+       zpff->report->field[1]->value[0] = 0x02;
+       zpff->report->field[2]->value[0] = 0x00;
+       zpff->report->field[3]->value[0] = 0x00;
+       hid_submit_report(hid, zpff->report, USB_DIR_OUT);
+
+       printk(KERN_INFO "Force feedback for Zeroplus based devices by "
+              "Anssi Hannula <anssi.hannula@gmail.com>\n");
+
+       return 0;
+}
index 778e575de35230831bebbfaa983a555f3754b40b..b03fd9b075df7cf836112f06531d199ef140c40b 100644 (file)
@@ -449,11 +449,6 @@ struct hid_device {                                                        /* device report descriptor */
        char phys[64];                                                  /* Device physical location */
        char uniq[64];                                                  /* Device unique identifier (serial #) */
 
-       void *ff_private;                                               /* Private data for the force-feedback driver */
-       void (*ff_exit)(struct hid_device*);                            /* Called by hid_exit_ff(hid) */
-       int (*ff_event)(struct hid_device *hid, struct input_dev *input,
-                       unsigned int type, unsigned int code, int value);
-
 #ifdef CONFIG_USB_HIDINPUT_POWERBOOK
        unsigned long pb_pressed_fn[NBITS(KEY_MAX)];
        unsigned long pb_pressed_numlock[NBITS(KEY_MAX)];
@@ -521,29 +516,22 @@ void hid_close(struct hid_device *);
 int hid_set_field(struct hid_field *, unsigned, __s32);
 void hid_submit_report(struct hid_device *, struct hid_report *, unsigned char dir);
 void hid_init_reports(struct hid_device *hid);
-struct hid_field *hid_find_field_by_usage(struct hid_device *hid, __u32 wanted_usage, int type);
 int hid_wait_io(struct hid_device* hid);
 
 
 #ifdef CONFIG_HID_FF
 int hid_ff_init(struct hid_device *hid);
+
+int hid_lgff_init(struct hid_device *hid);
+int hid_tmff_init(struct hid_device *hid);
+int hid_zpff_init(struct hid_device *hid);
+#ifdef CONFIG_HID_PID
+int hid_pidff_init(struct hid_device *hid);
+#else
+static inline int hid_pidff_init(struct hid_device *hid) { return -ENODEV; }
+#endif
+
 #else
 static inline int hid_ff_init(struct hid_device *hid) { return -1; }
 #endif
-static inline void hid_ff_exit(struct hid_device *hid)
-{
-       if (hid->ff_exit)
-               hid->ff_exit(hid);
-}
-static inline int hid_ff_event(struct hid_device *hid, struct input_dev *input,
-                       unsigned int type, unsigned int code, int value)
-{
-       if (hid->ff_event)
-               return hid->ff_event(hid, input, type, code, value);
-       return -ENOSYS;
-}
-
-int hid_lgff_init(struct hid_device* hid);
-int hid_tmff_init(struct hid_device* hid);
-int hid_pid_init(struct hid_device* hid);
 
diff --git a/drivers/usb/input/pid.c b/drivers/usb/input/pid.c
deleted file mode 100644 (file)
index d9d9f65..0000000
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- *  PID Force feedback support for hid devices.
- *
- *  Copyright (c) 2002 Rodrigo Damazio.
- *  Portions by Johann Deneux and Bjorn Augustson
- */
-
-/*
- * 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
- *
- * Should you need to contact me, the author, you can do so by
- * e-mail - mail your message to <rdamazio@lsi.usp.br>
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/smp_lock.h>
-#include <linux/spinlock.h>
-#include <linux/input.h>
-#include <linux/usb.h>
-#include "hid.h"
-#include "pid.h"
-
-#define CHECK_OWNERSHIP(i, hid_pid)    \
-       ((i) < FF_EFFECTS_MAX && i >= 0 && \
-       test_bit(FF_PID_FLAGS_USED, &hid_pid->effects[(i)].flags) && \
-       (current->pid == 0 || \
-       (hid_pid)->effects[(i)].owner == current->pid))
-
-/* Called when a transfer is completed */
-static void hid_pid_ctrl_out(struct urb *u, struct pt_regs *regs)
-{
-       dev_dbg(&u->dev->dev, "hid_pid_ctrl_out - Transfer Completed\n");
-}
-
-static void hid_pid_exit(struct hid_device *hid)
-{
-       struct hid_ff_pid *private = hid->ff_private;
-
-       if (private->urbffout) {
-               usb_kill_urb(private->urbffout);
-               usb_free_urb(private->urbffout);
-       }
-}
-
-static int pid_upload_periodic(struct hid_ff_pid *pid, struct ff_effect *effect, int is_update)
-{
-       dev_info(&pid->hid->dev->dev, "requested periodic force upload\n");
-       return 0;
-}
-
-static int pid_upload_constant(struct hid_ff_pid *pid, struct ff_effect *effect, int is_update)
-{
-       dev_info(&pid->hid->dev->dev, "requested constant force upload\n");
-       return 0;
-}
-
-static int pid_upload_condition(struct hid_ff_pid *pid, struct ff_effect *effect, int is_update)
-{
-       dev_info(&pid->hid->dev->dev, "requested Condition force upload\n");
-       return 0;
-}
-
-static int pid_upload_ramp(struct hid_ff_pid *pid, struct ff_effect *effect, int is_update)
-{
-       dev_info(&pid->hid->dev->dev, "request ramp force upload\n");
-       return 0;
-}
-
-static int hid_pid_event(struct hid_device *hid, struct input_dev *input,
-                        unsigned int type, unsigned int code, int value)
-{
-       dev_dbg(&hid->dev->dev, "PID event received: type=%d,code=%d,value=%d.\n", type, code, value);
-
-       if (type != EV_FF)
-               return -1;
-
-       return 0;
-}
-
-/* Lock must be held by caller */
-static void hid_pid_ctrl_playback(struct hid_device *hid, struct hid_pid_effect *effect, int play)
-{
-       if (play)
-               set_bit(FF_PID_FLAGS_PLAYING, &effect->flags);
-       else
-               clear_bit(FF_PID_FLAGS_PLAYING, &effect->flags);
-}
-
-static int hid_pid_erase(struct input_dev *dev, int id)
-{
-       struct hid_device *hid = dev->private;
-       struct hid_ff_pid *pid = hid->ff_private;
-       struct hid_field *field;
-       unsigned long flags;
-       int ret;
-
-       if (!CHECK_OWNERSHIP(id, pid))
-               return -EACCES;
-
-       /* Find report */
-       field = hid_find_field_by_usage(hid, HID_UP_PID | FF_PID_USAGE_BLOCK_FREE,
-                                       HID_OUTPUT_REPORT);
-       if (!field) {
-               dev_err(&hid->dev->dev, "couldn't find report\n");
-               return -EIO;
-       }
-
-       ret = hid_set_field(field, 0, pid->effects[id].device_id);
-       if (ret) {
-               dev_err(&hid->dev->dev, "couldn't set field\n");
-               return ret;
-       }
-
-       hid_submit_report(hid, field->report, USB_DIR_OUT);
-
-       spin_lock_irqsave(&pid->lock, flags);
-       hid_pid_ctrl_playback(hid, pid->effects + id, 0);
-       pid->effects[id].flags = 0;
-       spin_unlock_irqrestore(&pid->lock, flags);
-
-       return 0;
-}
-
-/* Erase all effects this process owns */
-static int hid_pid_flush(struct input_dev *dev, struct file *file)
-{
-       struct hid_device *hid = dev->private;
-       struct hid_ff_pid *pid = hid->ff_private;
-       int i;
-
-       /*NOTE: no need to lock here. The only times EFFECT_USED is
-          modified is when effects are uploaded or when an effect is
-          erased. But a process cannot close its dev/input/eventX fd
-          and perform ioctls on the same fd all at the same time */
-       /*FIXME: multiple threads, anyone? */
-       for (i = 0; i < dev->ff_effects_max; ++i)
-               if (current->pid == pid->effects[i].owner
-                   && test_bit(FF_PID_FLAGS_USED, &pid->effects[i].flags))
-                       if (hid_pid_erase(dev, i))
-                               dev_warn(&hid->dev->dev, "erase effect %d failed", i);
-
-       return 0;
-}
-
-static int hid_pid_upload_effect(struct input_dev *dev,
-                                struct ff_effect *effect)
-{
-       struct hid_ff_pid *pid_private = (struct hid_ff_pid *)(dev->private);
-       int ret;
-       int is_update;
-       unsigned long flags;
-
-       dev_dbg(&pid_private->hid->dev->dev, "upload effect called: effect_type=%x\n", effect->type);
-       /* Check this effect type is supported by this device */
-       if (!test_bit(effect->type, dev->ffbit)) {
-               dev_dbg(&pid_private->hid->dev->dev,
-                       "invalid kind of effect requested.\n");
-               return -EINVAL;
-       }
-
-       /*
-        * If we want to create a new effect, get a free id
-        */
-       if (effect->id == -1) {
-               int id = 0;
-
-               // Spinlock so we don`t get a race condition when choosing IDs
-               spin_lock_irqsave(&pid_private->lock, flags);
-
-               while (id < FF_EFFECTS_MAX)
-                       if (!test_and_set_bit(FF_PID_FLAGS_USED, &pid_private->effects[id++].flags))
-                               break;
-
-               if (id == FF_EFFECTS_MAX) {
-                       spin_unlock_irqrestore(&pid_private->lock, flags);
-// TEMP - We need to get ff_effects_max correctly first:  || id >= dev->ff_effects_max) {
-                       dev_dbg(&pid_private->hid->dev->dev, "Not enough device memory\n");
-                       return -ENOMEM;
-               }
-
-               effect->id = id;
-               dev_dbg(&pid_private->hid->dev->dev, "effect ID is %d.\n", id);
-               pid_private->effects[id].owner = current->pid;
-               pid_private->effects[id].flags = (1 << FF_PID_FLAGS_USED);
-               spin_unlock_irqrestore(&pid_private->lock, flags);
-
-               is_update = FF_PID_FALSE;
-       } else {
-               /* We want to update an effect */
-               if (!CHECK_OWNERSHIP(effect->id, pid_private))
-                       return -EACCES;
-
-               /* Parameter type cannot be updated */
-               if (effect->type != pid_private->effects[effect->id].effect.type)
-                       return -EINVAL;
-
-               /* Check the effect is not already being updated */
-               if (test_bit(FF_PID_FLAGS_UPDATING, &pid_private->effects[effect->id].flags))
-                       return -EAGAIN;
-
-               is_update = FF_PID_TRUE;
-       }
-
-       /*
-        * Upload the effect
-        */
-       switch (effect->type) {
-       case FF_PERIODIC:
-               ret = pid_upload_periodic(pid_private, effect, is_update);
-               break;
-
-       case FF_CONSTANT:
-               ret = pid_upload_constant(pid_private, effect, is_update);
-               break;
-
-       case FF_SPRING:
-       case FF_FRICTION:
-       case FF_DAMPER:
-       case FF_INERTIA:
-               ret = pid_upload_condition(pid_private, effect, is_update);
-               break;
-
-       case FF_RAMP:
-               ret = pid_upload_ramp(pid_private, effect, is_update);
-               break;
-
-       default:
-               dev_dbg(&pid_private->hid->dev->dev,
-                       "invalid type of effect requested - %x.\n",
-                       effect->type);
-               return -EINVAL;
-       }
-       /* If a packet was sent, forbid new updates until we are notified
-        * that the packet was updated
-        */
-       if (ret == 0)
-               set_bit(FF_PID_FLAGS_UPDATING, &pid_private->effects[effect->id].flags);
-       pid_private->effects[effect->id].effect = *effect;
-       return ret;
-}
-
-int hid_pid_init(struct hid_device *hid)
-{
-       struct hid_ff_pid *private;
-       struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
-       struct input_dev *input_dev = hidinput->input;
-
-       private = hid->ff_private = kzalloc(sizeof(struct hid_ff_pid), GFP_KERNEL);
-       if (!private)
-               return -ENOMEM;
-
-       private->hid = hid;
-
-       hid->ff_exit = hid_pid_exit;
-       hid->ff_event = hid_pid_event;
-
-       /* Open output URB */
-       if (!(private->urbffout = usb_alloc_urb(0, GFP_KERNEL))) {
-               kfree(private);
-               return -1;
-       }
-
-       usb_fill_control_urb(private->urbffout, hid->dev, 0,
-                            (void *)&private->ffcr, private->ctrl_buffer, 8,
-                            hid_pid_ctrl_out, hid);
-
-       input_dev->upload_effect = hid_pid_upload_effect;
-       input_dev->flush = hid_pid_flush;
-       input_dev->ff_effects_max = 8;  // A random default
-       set_bit(EV_FF, input_dev->evbit);
-       set_bit(EV_FF_STATUS, input_dev->evbit);
-
-       spin_lock_init(&private->lock);
-
-       printk(KERN_INFO "Force feedback driver for PID devices by Rodrigo Damazio <rdamazio@lsi.usp.br>.\n");
-
-       return 0;
-}
diff --git a/drivers/usb/input/pid.h b/drivers/usb/input/pid.h
deleted file mode 100644 (file)
index a2cb962..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- *  PID Force feedback support for hid devices.
- *
- *  Copyright (c) 2002 Rodrigo Damazio.
- */
-
-/*
- * 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
- *
- * Should you need to contact me, the author, you can do so by
- * e-mail - mail your message to <rdamazio@lsi.usp.br>
- */
-
-#define FF_EFFECTS_MAX 64
-
-#define FF_PID_FLAGS_USED      1       /* If the effect exists */
-#define FF_PID_FLAGS_UPDATING  2       /* If the effect is being updated */
-#define FF_PID_FLAGS_PLAYING   3       /* If the effect is currently being played */
-
-#define FF_PID_FALSE   0
-#define FF_PID_TRUE    1
-
-struct hid_pid_effect {
-       unsigned long flags;
-       pid_t owner;
-       unsigned int device_id; /* The device-assigned ID */
-       struct ff_effect effect;
-};
-
-struct hid_ff_pid {
-       struct hid_device *hid;
-       unsigned long gain;
-
-       struct urb *urbffout;
-       struct usb_ctrlrequest ffcr;
-       spinlock_t lock;
-
-       unsigned char ctrl_buffer[8];
-
-       struct hid_pid_effect effects[FF_EFFECTS_MAX];
-};
-
-/*
- * Constants from the PID usage table (still far from complete)
- */
-
-#define FF_PID_USAGE_BLOCK_LOAD        0x89UL
-#define FF_PID_USAGE_BLOCK_FREE                0x90UL
-#define FF_PID_USAGE_NEW_EFFECT        0xABUL
-#define FF_PID_USAGE_POOL_REPORT       0x7FUL
index 0222d92842b8ba79e89404d58ebcd06c729e8a2a..8006e51c34bb108e28d40b5956f8d29f47a146ef 100644 (file)
@@ -1015,7 +1015,7 @@ void usb_serial_disconnect(struct usb_interface *interface)
        dev_info(dev, "device disconnected\n");
 }
 
-static struct tty_operations serial_ops = {
+static const struct tty_operations serial_ops = {
        .open =                 serial_open,
        .close =                serial_close,
        .write =                serial_write,
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 e0ef3328942c44ff0eb09f249388aca98cc1cbcf..daaa486159cf37ae64d5329150466bf839272bdc 100644 (file)
@@ -53,6 +53,11 @@ config FB
          (e.g. an accelerated X server) and that are not frame buffer
          device-aware may cause unexpected results. If unsure, say N.
 
+config FB_DDC
+       tristate
+       depends on FB && I2C && I2C_ALGOBIT
+       default n
+
 config FB_CFB_FILLRECT
        tristate
        depends on FB
@@ -183,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.
 
@@ -398,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.
 
@@ -696,6 +701,7 @@ config FB_NVIDIA
        depends on FB && PCI
        select I2C_ALGOBIT if FB_NVIDIA_I2C
        select I2C if FB_NVIDIA_I2C
+       select FB_DDC if FB_NVIDIA_I2C
        select FB_MODE_HELPERS
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
@@ -734,6 +740,7 @@ config FB_RIVA
        depends on FB && PCI
        select I2C_ALGOBIT if FB_RIVA_I2C
        select I2C if FB_RIVA_I2C
+       select FB_DDC if FB_RIVA_I2C
        select FB_MODE_HELPERS
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
@@ -764,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
@@ -822,6 +829,7 @@ config FB_I810_I2C
        depends on FB_I810 && FB_I810_GTF
        select I2C
        select I2C_ALGOBIT
+       select FB_DDC
        help
 
 config FB_INTEL
@@ -857,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
@@ -1012,6 +1020,7 @@ config FB_RADEON
        depends on FB && PCI
        select I2C_ALGOBIT if FB_RADEON_I2C
        select I2C if FB_RADEON_I2C
+       select FB_DDC if FB_RADEON_I2C
        select FB_MODE_HELPERS
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
@@ -1053,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
@@ -1140,6 +1149,7 @@ config FB_SAVAGE
        depends on FB && PCI && EXPERIMENTAL
        select I2C_ALGOBIT if FB_SAVAGE_I2C
        select I2C if FB_SAVAGE_I2C
+       select FB_DDC if FB_SAVAGE_I2C
        select FB_MODE_HELPERS
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
@@ -1619,7 +1629,8 @@ config FB_VIRTUAL
          kernel option `video=vfb:'.
 
          To compile this driver as a module, choose M here: the
-         module will be called vfb.
+         module will be called vfb. In order to load it, you must use
+         the vfb_enable=1 option.
 
          If unsure, say N.
 if VT
index 481c6c9695f821da3bd133017bc4a9c3823046be..a6980e9a2481beb4e15bf06baa87f143b6068726 100644 (file)
@@ -18,6 +18,7 @@ obj-$(CONFIG_FB_CFB_FILLRECT)  += cfbfillrect.o
 obj-$(CONFIG_FB_CFB_COPYAREA)  += cfbcopyarea.o
 obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
 obj-$(CONFIG_FB_MACMODES)      += macmodes.o
+obj-$(CONFIG_FB_DDC)           += fb_ddc.o
 
 # Hardware specific drivers go first
 obj-$(CONFIG_FB_RETINAZ3)         += retz3fb.o
index 55fb8b04489b77ea3caf04ad01a1983b6054fa76..b04f49fb976ac3fe72d1f6d9bb955afccda1b012 100644 (file)
@@ -355,5 +355,9 @@ static inline void wait_for_idle(struct atyfb_par *par)
 
 extern void aty_reset_engine(const struct atyfb_par *par);
 extern void aty_init_engine(struct atyfb_par *par, struct fb_info *info);
-extern void aty_st_pll_ct(int offset, u8 val, const struct atyfb_par *par);
 extern u8   aty_ld_pll_ct(int offset, const struct atyfb_par *par);
+
+void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
+void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
+void atyfb_imageblit(struct fb_info *info, const struct fb_image *image);
+
index 19a71f045784008c3a278be54f1f42f19cfda6c9..b45c9fd1b3307af0c712edd78fe32011f9e3d485 100644 (file)
@@ -240,9 +240,6 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
 static int atyfb_blank(int blank, struct fb_info *info);
 static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg);
-extern void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
-extern void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
-extern void atyfb_imageblit(struct fb_info *info, const struct fb_image *image);
 #ifdef __sparc__
 static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma);
 #endif
@@ -3863,6 +3860,7 @@ static int __devinit atyfb_setup(char *options)
 
 static int __devinit atyfb_init(void)
 {
+    int err1 = 1, err2 = 1;
 #ifndef MODULE
     char *option = NULL;
 
@@ -3872,12 +3870,13 @@ static int __devinit atyfb_init(void)
 #endif
 
 #ifdef CONFIG_PCI
-    pci_register_driver(&atyfb_driver);
+    err1 = pci_register_driver(&atyfb_driver);
 #endif
 #ifdef CONFIG_ATARI
-    atyfb_atari_probe();
+    err2 = atyfb_atari_probe();
 #endif
-    return 0;
+
+    return (err1 && err2) ? -ENODEV : 0;
 }
 
 static void __exit atyfb_exit(void)
index e7056934c6a831c06620fd6ea1a45d1b689c3ead..5080816be653de4802a523d364ef720d394d0808 100644 (file)
@@ -27,7 +27,7 @@ u8 aty_ld_pll_ct(int offset, const struct atyfb_par *par)
        return res;
 }
 
-void aty_st_pll_ct(int offset, u8 val, const struct atyfb_par *par)
+static void aty_st_pll_ct(int offset, u8 val, const struct atyfb_par *par)
 {
        /* write addr byte */
        aty_st_8(CLOCK_CNTL_ADDR, ((offset << 2) & PLL_ADDR) | PLL_WR_EN, par);
index 9aaca58c074ac6c4926d55608ae98bae7aab0c9f..676754520099ca8e1ad53f52940b0ba0895c23b2 100644 (file)
@@ -16,8 +16,6 @@
 #include "radeonfb.h"
 #include "../edid.h"
 
-#define RADEON_DDC     0x50
-
 static void radeon_gpio_setscl(void* data, int state)
 {
        struct radeon_i2c_chan  *chan = data;
@@ -138,108 +136,10 @@ void radeon_delete_i2c_busses(struct radeonfb_info *rinfo)
        rinfo->i2c[3].rinfo = NULL;
 }
 
-
-static u8 *radeon_do_probe_i2c_edid(struct radeon_i2c_chan *chan)
-{
-       u8 start = 0x0;
-       struct i2c_msg msgs[] = {
-               {
-                       .addr   = RADEON_DDC,
-                       .len    = 1,
-                       .buf    = &start,
-               }, {
-                       .addr   = RADEON_DDC,
-                       .flags  = I2C_M_RD,
-                       .len    = EDID_LENGTH,
-               },
-       };
-       u8 *buf;
-
-       buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
-       if (!buf) {
-               dev_warn(&chan->rinfo->pdev->dev, "Out of memory!\n");
-               return NULL;
-       }
-       msgs[1].buf = buf;
-
-       if (i2c_transfer(&chan->adapter, msgs, 2) == 2)
-               return buf;
-       dev_dbg(&chan->rinfo->pdev->dev, "Unable to read EDID block.\n");
-       kfree(buf);
-       return NULL;
-}
-
-
-int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, u8 **out_edid)
+int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn,
+                              u8 **out_edid)
 {
-       u32 reg = rinfo->i2c[conn-1].ddc_reg;
-       u8 *edid = NULL;
-       int i, j;
-
-       OUTREG(reg, INREG(reg) & 
-                       ~(VGA_DDC_DATA_OUTPUT | VGA_DDC_CLK_OUTPUT));
-
-       OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN));
-       (void)INREG(reg);
-
-       for (i = 0; i < 3; i++) {
-               /* For some old monitors we need the
-                * following process to initialize/stop DDC
-                */
-               OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN));
-               (void)INREG(reg);
-               msleep(13);
-
-               OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN));
-               (void)INREG(reg);
-               for (j = 0; j < 5; j++) {
-                       msleep(10);
-                       if (INREG(reg) & VGA_DDC_CLK_INPUT)
-                               break;
-               }
-               if (j == 5)
-                       continue;
-
-               OUTREG(reg, INREG(reg) | VGA_DDC_DATA_OUT_EN);
-               (void)INREG(reg);
-               msleep(15);
-               OUTREG(reg, INREG(reg) | VGA_DDC_CLK_OUT_EN);
-               (void)INREG(reg);
-               msleep(15);
-               OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN));
-               (void)INREG(reg);
-               msleep(15);
-
-               /* Do the real work */
-               edid = radeon_do_probe_i2c_edid(&rinfo->i2c[conn-1]);
-
-               OUTREG(reg, INREG(reg) | 
-                               (VGA_DDC_DATA_OUT_EN | VGA_DDC_CLK_OUT_EN));
-               (void)INREG(reg);
-               msleep(15);
-               
-               OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN));
-               (void)INREG(reg);
-               for (j = 0; j < 10; j++) {
-                       msleep(10);
-                       if (INREG(reg) & VGA_DDC_CLK_INPUT)
-                               break;
-               }
-
-               OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN));
-               (void)INREG(reg);
-               msleep(15);
-               OUTREG(reg, INREG(reg) |
-                               (VGA_DDC_DATA_OUT_EN | VGA_DDC_CLK_OUT_EN));
-               (void)INREG(reg);
-               if (edid)
-                       break;
-       }
-       /* Release the DDC lines when done or the Apple Cinema HD display
-        * will switch off
-        */
-       OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN | VGA_DDC_DATA_OUT_EN));
-       (void)INREG(reg);
+       u8 *edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter);
 
        if (out_edid)
                *out_edid = edid;
index 365de5dcc888edf9c37766276f091ae689da648e..9a2b0d69b0ae7ebdb8bc0dac91a686e986c27f11 100644 (file)
@@ -86,6 +86,9 @@ static struct radeon_device_id radeon_workaround_list[] = {
        BUGFIX("Samsung P35",
               PCI_VENDOR_ID_SAMSUNG, 0xc00c,
               radeon_pm_off, radeon_reinitialize_M10),
+       BUGFIX("Acer Aspire 2010",
+              PCI_VENDOR_ID_AI, 0x0061,
+              radeon_pm_off, radeon_reinitialize_M10),
        { .ident = NULL }
 };
 
index f25d5d648333cb6665529154aeaec90184da02b5..ef5c16f7f5a64852b1505fbab982f8f63f6b899e 100644 (file)
@@ -8,6 +8,7 @@
  *     <c.pellegrin@exadron.com>
  *
  * PM support added by Rodolfo Giometti <giometti@linux.it>
+ * Cursor enable/disable by Rodolfo Giometti <giometti@linux.it>
  *
  * Copyright 2002 MontaVista Software
  * Author: MontaVista Software, Inc.
@@ -110,6 +111,10 @@ static struct fb_var_screeninfo au1100fb_var __initdata = {
 
 static struct au1100fb_drv_info drv_info;
 
+static int nocursor = 0;
+module_param(nocursor, int, 0644);
+MODULE_PARM_DESC(nocursor, "cursor enable/disable");
+
 /*
  * Set hardware with var settings. This will enable the controller with a specific
  * mode, normally validated with the fb_check_var method
@@ -422,6 +427,17 @@ int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
        return 0;
 }
 
+/* fb_cursor
+ * Used to disable cursor drawing...
+ */
+int au1100fb_fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
+{
+       if (nocursor)
+               return 0;
+       else
+               return -EINVAL; /* just to force soft_cursor() call */
+}
+
 static struct fb_ops au1100fb_ops =
 {
        .owner                  = THIS_MODULE,
@@ -433,6 +449,7 @@ static struct fb_ops au1100fb_ops =
        .fb_imageblit           = cfb_imageblit,
        .fb_rotate              = au1100fb_fb_rotate,
        .fb_mmap                = au1100fb_fb_mmap,
+       .fb_cursor              = au1100fb_fb_cursor,
 };
 
 
@@ -677,7 +694,7 @@ int au1100fb_setup(char *options)
        if (options) {
                while ((this_opt = strsep(&options,",")) != NULL) {
                        /* Panel option */
-               if (!strncmp(this_opt, "panel:", 6)) {
+                       if (!strncmp(this_opt, "panel:", 6)) {
                                int i;
                                this_opt += 6;
                                for (i = 0; i < num_panels; i++) {
@@ -685,13 +702,18 @@ int au1100fb_setup(char *options)
                                                     known_lcd_panels[i].name,
                                                        strlen(this_opt))) {
                                                panel_idx = i;
-                                       break;
+                                               break;
+                                       }
                                }
-                       }
                                if (i >= num_panels) {
                                        print_warn("Panel %s not supported!", this_opt);
                                }
                        }
+                       if (!strncmp(this_opt, "nocursor", 8)) {
+                               this_opt += 8;
+                               nocursor = 1;
+                               print_info("Cursor disabled");
+                       }
                        /* Mode option (only option that start with digit) */
                        else if (isdigit(this_opt[0])) {
                                mode = kmalloc(strlen(this_opt) + 1, GFP_KERNEL);
@@ -700,7 +722,7 @@ int au1100fb_setup(char *options)
                        /* Unsupported option */
                        else {
                                print_warn("Unsupported option \"%s\"", this_opt);
-               }
+                       }
                }
        }
 
index 1b4f75d1f8a949bb3321733d0aa5e61fe7bdf04f..8c041daa3a15b264b5825141a5382f92a526fa4c 100644 (file)
@@ -133,6 +133,7 @@ static int info_idx = -1;
 
 /* console rotation */
 static int rotate;
+static int fbcon_has_sysfs;
 
 static const struct consw fb_con;
 
@@ -396,9 +397,8 @@ static void fb_flashcursor(void *private)
                vc = vc_cons[ops->currcon].d;
 
        if (!vc || !CON_IS_VISIBLE(vc) ||
-           fbcon_is_inactive(vc, info) ||
            registered_fb[con2fb_map[vc->vc_num]] != info ||
-           vc_cons[ops->currcon].d->vc_deccm != 1) {
+           vc->vc_deccm != 1) {
                release_console_sem();
                return;
        }
@@ -2166,7 +2166,12 @@ static int fbcon_switch(struct vc_data *vc)
                        fbcon_del_cursor_timer(old_info);
        }
 
-       fbcon_add_cursor_timer(info);
+       if (fbcon_is_inactive(vc, info) ||
+           ops->blank_state != FB_BLANK_UNBLANK)
+               fbcon_del_cursor_timer(info);
+       else
+               fbcon_add_cursor_timer(info);
+
        set_blitting_type(vc, info);
        ops->cursor_reset = 1;
 
@@ -2276,10 +2281,11 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
                        update_screen(vc);
        }
 
-       if (!blank)
-               fbcon_add_cursor_timer(info);
-       else
+       if (fbcon_is_inactive(vc, info) ||
+           ops->blank_state != FB_BLANK_UNBLANK)
                fbcon_del_cursor_timer(info);
+       else
+               fbcon_add_cursor_timer(info);
 
        return 0;
 }
@@ -3161,11 +3167,26 @@ static struct class_device_attribute class_device_attrs[] = {
 
 static int fbcon_init_class_device(void)
 {
-       int i;
+       int i, error = 0;
+
+       fbcon_has_sysfs = 1;
+
+       for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) {
+               error = class_device_create_file(fbcon_class_device,
+                                                &class_device_attrs[i]);
+
+               if (error)
+                       break;
+       }
+
+       if (error) {
+               while (--i >= 0)
+                       class_device_remove_file(fbcon_class_device,
+                                                &class_device_attrs[i]);
+
+               fbcon_has_sysfs = 0;
+       }
 
-       for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
-               class_device_create_file(fbcon_class_device,
-                                        &class_device_attrs[i]);
        return 0;
 }
 
@@ -3225,7 +3246,10 @@ static void fbcon_exit(void)
                        module_put(info->fbops->owner);
 
                        if (info->fbcon_par) {
+                               struct fbcon_ops *ops = info->fbcon_par;
+
                                fbcon_del_cursor_timer(info);
+                               kfree(ops->cursor_src);
                                kfree(info->fbcon_par);
                                info->fbcon_par = NULL;
                        }
@@ -3271,9 +3295,13 @@ static void __exit fbcon_deinit_class_device(void)
 {
        int i;
 
-       for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
-               class_device_remove_file(fbcon_class_device,
-                                        &class_device_attrs[i]);
+       if (fbcon_has_sysfs) {
+               for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
+                       class_device_remove_file(fbcon_class_device,
+                                                &class_device_attrs[i]);
+
+               fbcon_has_sysfs = 0;
+       }
 }
 
 static void __exit fb_console_exit(void)
index f244ad066d688852af1826a8f3b0aabc550c0b6a..b9386d168c0499a260a99b9b9c3d76fec8828d27 100644 (file)
@@ -80,6 +80,8 @@ struct fbcon_ops {
        char  *cursor_data;
        u8    *fontbuffer;
        u8    *fontdata;
+       u8    *cursor_src;
+       u32    cursor_size;
        u32    fd_size;
 };
     /*
index 4481c80b8b2a12b533b206cda6e19775ea6bbe1b..825e6d6972a72cbecb51a1194fcdaf16f0cf0a7e 100644 (file)
@@ -391,7 +391,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
        ops->cursor_reset = 0;
 }
 
-int ccw_update_start(struct fb_info *info)
+static int ccw_update_start(struct fb_info *info)
 {
        struct fbcon_ops *ops = info->fbcon_par;
        u32 yoffset;
index 7f92c06afea7a7b749e9ce8e7dba20b691f8ac43..c637e6318803796e6b735b2f860227543cd0107d 100644 (file)
@@ -375,7 +375,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
        ops->cursor_reset = 0;
 }
 
-int cw_update_start(struct fb_info *info)
+static int cw_update_start(struct fb_info *info)
 {
        struct fbcon_ops *ops = info->fbcon_par;
        u32 vxres = GETVXRES(ops->p->scrollmode, info);
index ab91005e64dc67d07688dc24a175b2fa68d45f83..1473506df5d0654cba5d2bf6e5281ccc6b186870 100644 (file)
@@ -415,7 +415,7 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode,
        ops->cursor_reset = 0;
 }
 
-int ud_update_start(struct fb_info *info)
+static int ud_update_start(struct fb_info *info)
 {
        struct fbcon_ops *ops = info->fbcon_par;
        int xoffset, yoffset;
index 557c563e4aed2033a9ce33ea850a85b87ff35d04..7d07d838356904e0b14462a9f50911abaaa92257 100644 (file)
 
 int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
+       struct fbcon_ops *ops = info->fbcon_par;
        unsigned int scan_align = info->pixmap.scan_align - 1;
        unsigned int buf_align = info->pixmap.buf_align - 1;
        unsigned int i, size, dsize, s_pitch, d_pitch;
        struct fb_image *image;
-       u8 *dst, *src;
+       u8 *dst;
 
        if (info->state != FBINFO_STATE_RUNNING)
                return 0;
@@ -32,11 +33,19 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
        s_pitch = (cursor->image.width + 7) >> 3;
        dsize = s_pitch * cursor->image.height;
 
-       src = kmalloc(dsize + sizeof(struct fb_image), GFP_ATOMIC);
-       if (!src)
-               return -ENOMEM;
+       if (dsize + sizeof(struct fb_image) != ops->cursor_size) {
+               if (ops->cursor_src != NULL)
+                       kfree(ops->cursor_src);
+               ops->cursor_size = dsize + sizeof(struct fb_image);
 
-       image = (struct fb_image *) (src + dsize);
+               ops->cursor_src = kmalloc(ops->cursor_size, GFP_ATOMIC);
+               if (!ops->cursor_src) {
+                       ops->cursor_size = 0;
+                       return -ENOMEM;
+               }
+       }
+
+       image = (struct fb_image *) (ops->cursor_src + dsize);
        *image = cursor->image;
        d_pitch = (s_pitch + scan_align) & ~scan_align;
 
@@ -48,21 +57,23 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
                switch (cursor->rop) {
                case ROP_XOR:
                        for (i = 0; i < dsize; i++)
-                               src[i] = image->data[i] ^ cursor->mask[i];
+                               ops->cursor_src[i] = image->data[i] ^
+                                       cursor->mask[i];
                        break;
                case ROP_COPY:
                default:
                        for (i = 0; i < dsize; i++)
-                               src[i] = image->data[i] & cursor->mask[i];
+                               ops->cursor_src[i] = image->data[i] &
+                                       cursor->mask[i];
                        break;
                }
        } else
-               memcpy(src, image->data, dsize);
+               memcpy(ops->cursor_src, image->data, dsize);
 
-       fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, image->height);
+       fb_pad_aligned_buffer(dst, d_pitch, ops->cursor_src, s_pitch,
+                             image->height);
        image->data = dst;
        info->fbops->fb_imageblit(info, image);
-       kfree(src);
        return 0;
 }
 
diff --git a/drivers/video/fb_ddc.c b/drivers/video/fb_ddc.c
new file mode 100644 (file)
index 0000000..3aa6ebf
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * driver/vide/fb_ddc.c - DDC/EDID read support.
+ *
+ *  Copyright (C) 2006 Dennis Munsie <dmunsie@cecropia.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/fb.h>
+#include <linux/i2c-algo-bit.h>
+
+#include "edid.h"
+
+#define DDC_ADDR       0x50
+
+static unsigned char *fb_do_probe_ddc_edid(struct i2c_adapter *adapter)
+{
+       unsigned char start = 0x0;
+       struct i2c_msg msgs[] = {
+               {
+                       .addr   = DDC_ADDR,
+                       .len    = 1,
+                       .buf    = &start,
+               }, {
+                       .addr   = DDC_ADDR,
+                       .flags  = I2C_M_RD,
+                       .len    = EDID_LENGTH,
+               }
+       };
+       unsigned char *buf;
+
+       buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
+       if (!buf) {
+               dev_warn(&adapter->dev, "unable to allocate memory for EDID "
+                        "block.\n");
+               return NULL;
+       }
+       msgs[1].buf = buf;
+
+       if (i2c_transfer(adapter, msgs, 2) == 2)
+               return buf;
+
+       dev_warn(&adapter->dev, "unable to read EDID block.\n");
+       kfree(buf);
+       return NULL;
+}
+
+unsigned char *fb_ddc_read(struct i2c_adapter *adapter)
+{
+       struct i2c_algo_bit_data *algo_data = adapter->algo_data;
+       unsigned char *edid = NULL;
+       int i, j;
+
+       algo_data->setscl(algo_data->data, 1);
+       algo_data->setscl(algo_data->data, 0);
+
+       for (i = 0; i < 3; i++) {
+               /* For some old monitors we need the
+                * following process to initialize/stop DDC
+                */
+               algo_data->setsda(algo_data->data, 0);
+               msleep(13);
+
+               algo_data->setscl(algo_data->data, 1);
+               for (j = 0; j < 5; j++) {
+                       msleep(10);
+                       if (algo_data->getscl(algo_data->data))
+                               break;
+               }
+               if (j == 5)
+                       continue;
+
+               algo_data->setsda(algo_data->data, 0);
+               msleep(15);
+               algo_data->setscl(algo_data->data, 0);
+               msleep(15);
+               algo_data->setsda(algo_data->data, 1);
+               msleep(15);
+
+               /* Do the real work */
+               edid = fb_do_probe_ddc_edid(adapter);
+               algo_data->setsda(algo_data->data, 0);
+               algo_data->setscl(algo_data->data, 0);
+               msleep(15);
+
+               algo_data->setscl(algo_data->data, 1);
+               for (j = 0; j < 10; j++) {
+                       msleep(10);
+                       if (algo_data->getscl(algo_data->data))
+                               break;
+               }
+
+               algo_data->setsda(algo_data->data, 1);
+               msleep(15);
+               algo_data->setscl(algo_data->data, 0);
+               if (edid)
+                       break;
+       }
+       /* Release the DDC lines when done or the Apple Cinema HD display
+        * will switch off
+        */
+       algo_data->setsda(algo_data->data, 0);
+       algo_data->setscl(algo_data->data, 0);
+
+       return edid;
+}
+
+EXPORT_SYMBOL_GPL(fb_ddc_read);
+
+MODULE_AUTHOR("Dennis Munsie <dmunsie@cecropia.com>");
+MODULE_DESCRIPTION("DDC/EDID reading support");
+MODULE_LICENSE("GPL");
index 17961e3ecaa07ed1b9572868e5af8055f1b91760..93ffcdd95f5026fd467116553b5c1335f872d89d 100644 (file)
@@ -554,7 +554,8 @@ static int fbmem_read_proc(char *buf, char **start, off_t offset,
        int clen;
 
        clen = 0;
-       for (fi = registered_fb; fi < &registered_fb[FB_MAX] && len < 4000; fi++)
+       for (fi = registered_fb; fi < &registered_fb[FB_MAX] && clen < 4000;
+            fi++)
                if (*fi)
                        clen += sprintf(buf + clen, "%d %s\n",
                                        (*fi)->node,
index c151dcf68786a1c5ca1987f209e83351db5159d7..d3a50417ed9a6ab09d16841e435597bf8f6da312 100644 (file)
@@ -20,6 +20,8 @@
 #include <linux/console.h>
 #include <linux/module.h>
 
+#define FB_SYSFS_FLAG_ATTR 1
+
 /**
  * framebuffer_alloc - creates a new frame buffer info structure
  *
@@ -483,12 +485,27 @@ static struct class_device_attribute class_device_attrs[] = {
 
 int fb_init_class_device(struct fb_info *fb_info)
 {
-       unsigned int i;
+       int i, error = 0;
+
        class_set_devdata(fb_info->class_device, fb_info);
 
-       for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
-               class_device_create_file(fb_info->class_device,
-                                        &class_device_attrs[i]);
+       fb_info->class_flag |= FB_SYSFS_FLAG_ATTR;
+
+       for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) {
+               error = class_device_create_file(fb_info->class_device,
+                                                &class_device_attrs[i]);
+
+               if (error)
+                       break;
+       }
+
+       if (error) {
+               while (--i >= 0)
+                       class_device_remove_file(fb_info->class_device,
+                                                &class_device_attrs[i]);
+               fb_info->class_flag &= ~FB_SYSFS_FLAG_ATTR;
+       }
+
        return 0;
 }
 
@@ -496,9 +513,13 @@ void fb_cleanup_class_device(struct fb_info *fb_info)
 {
        unsigned int i;
 
-       for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
-               class_device_remove_file(fb_info->class_device,
-                                        &class_device_attrs[i]);
+       if (fb_info->class_flag & FB_SYSFS_FLAG_ATTR) {
+               for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
+                       class_device_remove_file(fb_info->class_device,
+                                                &class_device_attrs[i]);
+
+               fb_info->class_flag &= ~FB_SYSFS_FLAG_ATTR;
+       }
 }
 
 #ifdef CONFIG_FB_BACKLIGHT
index 7d06b38e80a00f7e4f5d7ead2062a46da7e5730d..b38d805db3134673723716083703efa571c84c4a 100644 (file)
@@ -19,7 +19,6 @@
 #include "i810_main.h"
 #include "../edid.h"
 
-#define I810_DDC 0x50
 /* bit locations in the registers */
 #define SCL_DIR_MASK           0x0001
 #define SCL_DIR                        0x0002
@@ -150,53 +149,14 @@ void i810_delete_i2c_busses(struct i810fb_par *par)
        par->chan[2].par = NULL;
 }
 
-static u8 *i810_do_probe_i2c_edid(struct i810fb_i2c_chan *chan)
-{
-        u8 start = 0x0;
-        struct i2c_msg msgs[] = {
-                {
-                        .addr   = I810_DDC,
-                        .len    = 1,
-                        .buf    = &start,
-                }, {
-                        .addr   = I810_DDC,
-                        .flags  = I2C_M_RD,
-                        .len    = EDID_LENGTH,
-                },
-        };
-        u8 *buf;
-
-        buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
-        if (!buf) {
-               DPRINTK("i810-i2c: Failed to allocate memory\n");
-                return NULL;
-        }
-        msgs[1].buf = buf;
-
-        if (i2c_transfer(&chan->adapter, msgs, 2) == 2) {
-               DPRINTK("i810-i2c: I2C Transfer successful\n");
-                return buf;
-       }
-
-        DPRINTK("i810-i2c: Unable to read EDID block.\n");
-        kfree(buf);
-        return NULL;
-}
-
 int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid, int conn)
 {
        struct i810fb_par *par = info->par;
         u8 *edid = NULL;
-        int i;
 
        DPRINTK("i810-i2c: Probe DDC%i Bus\n", conn+1);
        if (conn < par->ddc_num) {
-               for (i = 0; i < 3; i++) {
-                       /* Do the real work */
-                       edid = i810_do_probe_i2c_edid(&par->chan[conn]);
-                       if (edid)
-                               break;
-               }
+               edid = fb_ddc_read(&par->chan[conn].adapter);
        } else {
                const u8 *e = fb_firmware_edid(info->device);
 
index d42edaccb84c732bab17286ef9b5fc90687ca419..b55a12d95eb22ebe641add5c6c9e9602803b2793 100644 (file)
@@ -1602,7 +1602,10 @@ static int i810fb_resume(struct pci_dev *dev)
        acquire_console_sem();
        pci_set_power_state(dev, PCI_D0);
        pci_restore_state(dev);
-       pci_enable_device(dev);
+
+       if (pci_enable_device(dev))
+               goto fail;
+
        pci_set_master(dev);
        agp_bind_memory(par->i810_gtt.i810_fb_memory,
                        par->fb.offset);
@@ -1611,6 +1614,7 @@ static int i810fb_resume(struct pci_dev *dev)
        i810fb_set_par(info);
        fb_set_suspend (info, 0);
        info->fbops->fb_blank(VESA_NO_BLANKING, info);
+fail:
        release_console_sem();
        return 0;
 }
index 4a57dabb77d4a1cf028d47b5f84f8643fb00f663..7acf01c181eeb6d622efa8d2f1615240089e4272 100644 (file)
@@ -2277,10 +2277,13 @@ static void __init matroxfb_init_params(void) {
        }
 }
 
-static void __init matrox_init(void) {
+static int __init matrox_init(void) {
+       int err;
+
        matroxfb_init_params();
-       pci_register_driver(&matroxfb_driver);
+       err = pci_register_driver(&matroxfb_driver);
        dev = -1;       /* accept all new devices... */
+       return err;
 }
 
 /* **************************** exit-time only **************************** */
@@ -2437,6 +2440,7 @@ static int __initdata initialized = 0;
 static int __init matroxfb_init(void)
 {
        char *option = NULL;
+       int err = 0;
 
        DBG(__FUNCTION__)
 
@@ -2448,11 +2452,11 @@ static int __init matroxfb_init(void)
                return -ENXIO;
        if (!initialized) {
                initialized = 1;
-               matrox_init();
+               err = matrox_init();
        }
        hotplug = 1;
        /* never return failure, user can hotplug matrox later... */
-       return 0;
+       return err;
 }
 
 module_init(matroxfb_init);
index 6849ab75d4034f12e5b70a69cf896a61b9b224a3..a32d1af79e07c4b349e2e88e65d8d9d4cf6bf4ab 100644 (file)
@@ -118,8 +118,19 @@ static unsigned int mbxfb_get_pixclock(unsigned int pixclock_ps,
        /* convert pixclock to KHz */
        pixclock = PICOS2KHZ(pixclock_ps);
 
+       /* PLL output freq = (ref_clk * M) / (N * 2^P)
+        *
+        * M: 1 to 63
+        * N: 1 to 7
+        * P: 0 to 7
+        */
+
+       /* RAPH: When N==1, the resulting pixel clock appears to
+        * get divided by 2. Preventing N=1 by starting the following
+        * loop at 2 prevents this. Is this a bug with my chip
+        * revision or something I dont understand? */
        for (m = 1; m < 64; m++) {
-               for (n = 1; n < 8; n++) {
+               for (n = 2; n < 8; n++) {
                        for (p = 0; p < 8; p++) {
                                clk = (ref_clk * m) / (n * (1 << p));
                                err = (clk > pixclock) ? (clk - pixclock) :
@@ -244,8 +255,8 @@ static int mbxfb_set_par(struct fb_info *info)
 
        /* setup resolution */
        gsctrl &= ~(FMsk(GSCTRL_GSWIDTH) | FMsk(GSCTRL_GSHEIGHT));
-       gsctrl |= Gsctrl_Width(info->var.xres - 1) |
-               Gsctrl_Height(info->var.yres - 1);
+       gsctrl |= Gsctrl_Width(info->var.xres) |
+               Gsctrl_Height(info->var.yres);
        writel(gsctrl, GSCTRL);
        udelay(1000);
 
@@ -402,8 +413,8 @@ static void __devinit setup_graphics(struct fb_info *fbi)
 {
        unsigned long gsctrl;
 
-       gsctrl = GSCTRL_GAMMA_EN | Gsctrl_Width(fbi->var.xres - 1) |
-               Gsctrl_Height(fbi->var.yres - 1);
+       gsctrl = GSCTRL_GAMMA_EN | Gsctrl_Width(fbi->var.xres) |
+               Gsctrl_Height(fbi->var.yres);
        switch (fbi->var.bits_per_pixel) {
        case 16:
                if (fbi->var.green.length == 5)
index 19eef3a090232854860ad993365993dc7e5f68f6..e48de3c9fd13ff0ee1f35df67a85281a719e26fd 100644 (file)
@@ -160,51 +160,12 @@ void nvidia_delete_i2c_busses(struct nvidia_par *par)
 
 }
 
-static u8 *nvidia_do_probe_i2c_edid(struct nvidia_i2c_chan *chan)
-{
-       u8 start = 0x0;
-       struct i2c_msg msgs[] = {
-               {
-                .addr = 0x50,
-                .len = 1,
-                .buf = &start,
-                }, {
-                    .addr = 0x50,
-                    .flags = I2C_M_RD,
-                    .len = EDID_LENGTH,
-                    },
-       };
-       u8 *buf;
-
-       if (!chan->par)
-               return NULL;
-
-       buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
-       if (!buf) {
-               dev_warn(&chan->par->pci_dev->dev, "Out of memory!\n");
-               return NULL;
-       }
-       msgs[1].buf = buf;
-
-       if (i2c_transfer(&chan->adapter, msgs, 2) == 2)
-               return buf;
-       dev_dbg(&chan->par->pci_dev->dev, "Unable to read EDID block.\n");
-       kfree(buf);
-       return NULL;
-}
-
 int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid)
 {
        struct nvidia_par *par = info->par;
-       u8 *edid = NULL;
-       int i;
-
-       for (i = 0; i < 3; i++) {
-               /* Do the real work */
-               edid = nvidia_do_probe_i2c_edid(&par->chan[conn - 1]);
-               if (edid)
-                       break;
-       }
+       u8 *edid;
+
+       edid = fb_ddc_read(&par->chan[conn - 1].adapter);
 
        if (!edid && conn == 1) {
                /* try to get from firmware */
index f8cd4c519aebf1125ba9e6a347be3cdc67f80418..eb24107bcc81f539a4a7e92b87fb5efb0523f9d1 100644 (file)
@@ -28,6 +28,9 @@
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
 #endif
+#ifdef CONFIG_BOOTX_TEXT
+#include <asm/btext.h>
+#endif
 
 #include "nv_local.h"
 #include "nv_type.h"
@@ -681,6 +684,13 @@ static int nvidiafb_set_par(struct fb_info *info)
 
        nvidia_vga_protect(par, 0);
 
+#ifdef CONFIG_BOOTX_TEXT
+       /* Update debug text engine */
+       btext_update_display(info->fix.smem_start,
+                            info->var.xres, info->var.yres,
+                            info->var.bits_per_pixel, info->fix.line_length);
+#endif
+
        NVTRACE_LEAVE();
        return 0;
 }
@@ -984,7 +994,10 @@ static int nvidiafb_resume(struct pci_dev *dev)
 
        if (par->pm_state != PM_EVENT_FREEZE) {
                pci_restore_state(dev);
-               pci_enable_device(dev);
+
+               if (pci_enable_device(dev))
+                       goto fail;
+
                pci_set_master(dev);
        }
 
@@ -993,6 +1006,7 @@ static int nvidiafb_resume(struct pci_dev *dev)
        fb_set_suspend (info, 0);
        nvidiafb_blank(FB_BLANK_UNBLANK, info);
 
+fail:
        release_console_sem();
        return 0;
 }
index bbb07106cd54b1b50f2a3de7cf769590a7a56536..3bc5da4a57ca5caeca7046b89cb7b1dbd412a5e0 100644 (file)
@@ -59,7 +59,7 @@
 #define LCCR3_INVALID_CONFIG_MASK (LCCR3_HSP|LCCR3_VSP|LCCR3_PCD|LCCR3_BPP)
 
 static void (*pxafb_backlight_power)(int);
-static void (*pxafb_lcd_power)(int);
+static void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *);
 
 static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *);
 static void set_ctrlr_state(struct pxafb_info *fbi, u_int state);
@@ -213,6 +213,48 @@ static unsigned int pxafb_display_dma_period(struct fb_var_screeninfo *var)
 extern unsigned int get_clk_frequency_khz(int info);
 #endif
 
+/*
+ * Select the smallest mode that allows the desired resolution to be
+ * displayed. If desired parameters can be rounded up.
+ */
+static struct pxafb_mode_info *pxafb_getmode(struct pxafb_mach_info *mach, struct fb_var_screeninfo *var)
+{
+       struct pxafb_mode_info *mode = NULL;
+       struct pxafb_mode_info *modelist = mach->modes;
+       unsigned int best_x = 0xffffffff, best_y = 0xffffffff;
+       unsigned int i;
+
+       for (i = 0 ; i < mach->num_modes ; i++) {
+               if (modelist[i].xres >= var->xres && modelist[i].yres >= var->yres &&
+                               modelist[i].xres < best_x && modelist[i].yres < best_y &&
+                               modelist[i].bpp >= var->bits_per_pixel ) {
+                       best_x = modelist[i].xres;
+                       best_y = modelist[i].yres;
+                       mode = &modelist[i];
+               }
+       }
+
+       return mode;
+}
+
+static void pxafb_setmode(struct fb_var_screeninfo *var, struct pxafb_mode_info *mode)
+{
+       var->xres               = mode->xres;
+       var->yres               = mode->yres;
+       var->bits_per_pixel     = mode->bpp;
+       var->pixclock           = mode->pixclock;
+       var->hsync_len          = mode->hsync_len;
+       var->left_margin        = mode->left_margin;
+       var->right_margin       = mode->right_margin;
+       var->vsync_len          = mode->vsync_len;
+       var->upper_margin       = mode->upper_margin;
+       var->lower_margin       = mode->lower_margin;
+       var->sync               = mode->sync;
+       var->grayscale          = mode->cmap_greyscale;
+       var->xres_virtual       = var->xres;
+       var->yres_virtual       = var->yres;
+}
+
 /*
  *  pxafb_check_var():
  *    Get the video params out of 'var'. If a value doesn't fit, round it up,
@@ -225,15 +267,29 @@ extern unsigned int get_clk_frequency_khz(int info);
 static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
        struct pxafb_info *fbi = (struct pxafb_info *)info;
+       struct pxafb_mach_info *inf = fbi->dev->platform_data;
 
        if (var->xres < MIN_XRES)
                var->xres = MIN_XRES;
        if (var->yres < MIN_YRES)
                var->yres = MIN_YRES;
-       if (var->xres > fbi->max_xres)
-               return -EINVAL;
-       if (var->yres > fbi->max_yres)
-               return -EINVAL;
+
+       if (inf->fixed_modes) {
+               struct pxafb_mode_info *mode;
+
+               mode = pxafb_getmode(inf, var);
+               if (!mode)
+                       return -EINVAL;
+               pxafb_setmode(var, mode);
+       } else {
+               if (var->xres > inf->modes->xres)
+                       return -EINVAL;
+               if (var->yres > inf->modes->yres)
+                       return -EINVAL;
+               if (var->bits_per_pixel > inf->modes->bpp)
+                       return -EINVAL;
+       }
+
        var->xres_virtual =
                max(var->xres_virtual, var->xres);
        var->yres_virtual =
@@ -693,7 +749,7 @@ static inline void __pxafb_lcd_power(struct pxafb_info *fbi, int on)
        pr_debug("pxafb: LCD power o%s\n", on ? "n" : "ff");
 
        if (pxafb_lcd_power)
-               pxafb_lcd_power(on);
+               pxafb_lcd_power(on, &fbi->fb.var);
 }
 
 static void pxafb_setup_gpio(struct pxafb_info *fbi)
@@ -869,9 +925,11 @@ static void set_ctrlr_state(struct pxafb_info *fbi, u_int state)
                 * registers.
                 */
                if (old_state == C_ENABLE) {
+                       __pxafb_lcd_power(fbi, 0);
                        pxafb_disable_controller(fbi);
                        pxafb_setup_gpio(fbi);
                        pxafb_enable_controller(fbi);
+                       __pxafb_lcd_power(fbi, 1);
                }
                break;
 
@@ -1049,6 +1107,8 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev)
        struct pxafb_info *fbi;
        void *addr;
        struct pxafb_mach_info *inf = dev->platform_data;
+       struct pxafb_mode_info *mode = inf->modes;
+       int i, smemlen;
 
        /* Alloc the pxafb_info and pseudo_palette in one step */
        fbi = kmalloc(sizeof(struct pxafb_info) + sizeof(u32) * 16, GFP_KERNEL);
@@ -1082,31 +1142,21 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev)
        addr = addr + sizeof(struct pxafb_info);
        fbi->fb.pseudo_palette  = addr;
 
-       fbi->max_xres                   = inf->xres;
-       fbi->fb.var.xres                = inf->xres;
-       fbi->fb.var.xres_virtual        = inf->xres;
-       fbi->max_yres                   = inf->yres;
-       fbi->fb.var.yres                = inf->yres;
-       fbi->fb.var.yres_virtual        = inf->yres;
-       fbi->max_bpp                    = inf->bpp;
-       fbi->fb.var.bits_per_pixel      = inf->bpp;
-       fbi->fb.var.pixclock            = inf->pixclock;
-       fbi->fb.var.hsync_len           = inf->hsync_len;
-       fbi->fb.var.left_margin         = inf->left_margin;
-       fbi->fb.var.right_margin        = inf->right_margin;
-       fbi->fb.var.vsync_len           = inf->vsync_len;
-       fbi->fb.var.upper_margin        = inf->upper_margin;
-       fbi->fb.var.lower_margin        = inf->lower_margin;
-       fbi->fb.var.sync                = inf->sync;
-       fbi->fb.var.grayscale           = inf->cmap_greyscale;
+       pxafb_setmode(&fbi->fb.var, mode);
+
        fbi->cmap_inverse               = inf->cmap_inverse;
        fbi->cmap_static                = inf->cmap_static;
+
        fbi->lccr0                      = inf->lccr0;
        fbi->lccr3                      = inf->lccr3;
        fbi->state                      = C_STARTUP;
        fbi->task_state                 = (u_char)-1;
-       fbi->fb.fix.smem_len            = fbi->max_xres * fbi->max_yres *
-                                         fbi->max_bpp / 8;
+
+       for (i = 0; i < inf->num_modes; i++) {
+               smemlen = mode[i].xres * mode[i].yres * mode[i].bpp / 8;
+               if (smemlen > fbi->fb.fix.smem_len)
+                       fbi->fb.fix.smem_len = smemlen;
+       }
 
        init_waitqueue_head(&fbi->ctrlr_wait);
        INIT_WORK(&fbi->task, pxafb_task, fbi);
@@ -1307,12 +1357,12 @@ int __init pxafb_probe(struct platform_device *dev)
            (inf->lccr0 & LCCR0_SDS) == LCCR0_Dual)
                 dev_warn(&dev->dev, "Dual panel only valid in passive mode\n");
         if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Pas &&
-             (inf->upper_margin || inf->lower_margin))
+             (inf->modes->upper_margin || inf->modes->lower_margin))
                 dev_warn(&dev->dev, "Upper and lower margins must be 0 in passive mode\n");
 #endif
 
-       dev_dbg(&dev->dev, "got a %dx%dx%d LCD\n",inf->xres, inf->yres, inf->bpp);
-       if (inf->xres == 0 || inf->yres == 0 || inf->bpp == 0) {
+       dev_dbg(&dev->dev, "got a %dx%dx%d LCD\n",inf->modes->xres, inf->modes->yres, inf->modes->bpp);
+       if (inf->modes->xres == 0 || inf->modes->yres == 0 || inf->modes->bpp == 0) {
                dev_err(&dev->dev, "Invalid resolution or bit depth\n");
                ret = -EINVAL;
                goto failed;
index 47f41f70db7a042c821ddc65832529487364f26b..7499a1c4bf790c9ecf51ba7093878080284facb6 100644 (file)
@@ -41,10 +41,6 @@ struct pxafb_info {
        struct fb_info          fb;
        struct device           *dev;
 
-       u_int                   max_bpp;
-       u_int                   max_xres;
-       u_int                   max_yres;
-
        /*
         * These are the addresses we mapped
         * the framebuffer memory region to.
index 4acde4f7dbf8925a159fce3a9594be4bd4727e4a..a433cc78ef90b1d7c11639c52c838ae56457f504 100644 (file)
@@ -393,8 +393,8 @@ static void riva_bl_init(struct riva_par *par)
        mutex_lock(&info->bl_mutex);
        info->bl_dev = bd;
        fb_bl_default_curve(info, 0,
-               0x158 * FB_BACKLIGHT_MAX / MAX_LEVEL,
-               0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL);
+               MIN_LEVEL * FB_BACKLIGHT_MAX / MAX_LEVEL,
+               FB_BACKLIGHT_MAX);
        mutex_unlock(&info->bl_mutex);
 
        down(&bd->sem);
@@ -784,7 +784,7 @@ static void riva_load_video_mode(struct fb_info *info)
        
        NVTRACE_ENTER();
        /* time to calculate */
-       rivafb_blank(1, info);
+       rivafb_blank(FB_BLANK_NORMAL, info);
 
        bpp = info->var.bits_per_pixel;
        if (bpp == 16 && info->var.green.length == 5)
@@ -917,7 +917,7 @@ static void riva_load_video_mode(struct fb_info *info)
        par->current_state = newmode;
        riva_load_state(par, &par->current_state);
        par->riva.LockUnlock(&par->riva, 0); /* important for HW cursor */
-       rivafb_blank(0, info);
+       rivafb_blank(FB_BLANK_UNBLANK, info);
        NVTRACE_LEAVE();
 }
 
@@ -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 9751c37c0bfd57de13b4c182090c2adcc0422dd7..c15b259af64401f770b83cdcda69db5a30bab20a 100644 (file)
@@ -25,8 +25,6 @@
 #include "rivafb.h"
 #include "../edid.h"
 
-#define RIVA_DDC       0x50
-
 static void riva_gpio_setscl(void* data, int state)
 {
        struct riva_i2c_chan    *chan = data;
@@ -158,50 +156,12 @@ void riva_delete_i2c_busses(struct riva_par *par)
        par->chan[2].par = NULL;
 }
 
-static u8 *riva_do_probe_i2c_edid(struct riva_i2c_chan *chan)
-{
-       u8 start = 0x0;
-       struct i2c_msg msgs[] = {
-               {
-                       .addr   = RIVA_DDC,
-                       .len    = 1,
-                       .buf    = &start,
-               }, {
-                       .addr   = RIVA_DDC,
-                       .flags  = I2C_M_RD,
-                       .len    = EDID_LENGTH,
-               },
-       };
-       u8 *buf;
-
-       if (!chan->par)
-               return NULL;
-
-       buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
-       if (!buf) {
-               dev_warn(&chan->par->pdev->dev, "Out of memory!\n");
-               return NULL;
-       }
-       msgs[1].buf = buf;
-
-       if (i2c_transfer(&chan->adapter, msgs, 2) == 2)
-               return buf;
-       dev_dbg(&chan->par->pdev->dev, "Unable to read EDID block.\n");
-       kfree(buf);
-       return NULL;
-}
-
 int riva_probe_i2c_connector(struct riva_par *par, int conn, u8 **out_edid)
 {
        u8 *edid = NULL;
-       int i;
 
-       for (i = 0; i < 3; i++) {
-               /* Do the real work */
-               edid = riva_do_probe_i2c_edid(&par->chan[conn-1]);
-               if (edid)
-                       break;
-       }
+       edid = fb_ddc_read(&par->chan[conn-1].adapter);
+
        if (out_edid)
                *out_edid = edid;
        if (!edid)
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 d7d810dbf0bdb6b1db553b35529eb99a651a2a25..3f94223b7f0ca86c4b76a01553c6b89240c388e9 100644 (file)
@@ -213,52 +213,15 @@ void savagefb_delete_i2c_busses(struct fb_info *info)
        par->chan.par = NULL;
 }
 
-static u8 *savage_do_probe_i2c_edid(struct savagefb_i2c_chan *chan)
-{
-       u8 start = 0x0;
-       struct i2c_msg msgs[] = {
-               {
-                       .addr   = SAVAGE_DDC,
-                       .len    = 1,
-                       .buf    = &start,
-               }, {
-                       .addr   = SAVAGE_DDC,
-                       .flags  = I2C_M_RD,
-                       .len    = EDID_LENGTH,
-               },
-       };
-       u8 *buf = NULL;
-
-       if (chan->par) {
-               buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
-
-               if (buf) {
-                       msgs[1].buf = buf;
-
-                       if (i2c_transfer(&chan->adapter, msgs, 2) != 2) {
-                               dev_dbg(&chan->par->pcidev->dev,
-                                       "Unable to read EDID block.\n");
-                               kfree(buf);
-                               buf = NULL;
-                       }
-               }
-       }
-
-       return buf;
-}
-
 int savagefb_probe_i2c_connector(struct fb_info *info, u8 **out_edid)
 {
        struct savagefb_par *par = info->par;
-       u8 *edid = NULL;
-       int i;
-
-       for (i = 0; i < 3; i++) {
-               /* Do the real work */
-               edid = savage_do_probe_i2c_edid(&par->chan);
-               if (edid)
-                       break;
-       }
+       u8 *edid;
+
+       if (par->chan.par)
+               edid = fb_ddc_read(&par->chan.adapter);
+       else
+               edid = NULL;
 
        if (!edid) {
                /* try to get from firmware */
index 7ecab87cef027cece07ad55c987bd96a280f4a39..59d12844b4dd9f2cffcabeb0b3ac126b08ff3b6c 100644 (file)
 #include <linux/types.h>
 #include <asm/io.h>
 #include <linux/fb.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <video/fbcon.h>
-#endif
 #include "sis.h"
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <linux/sisfb.h>
-#else
 #include <video/sisfb.h>
 #endif
-#endif
 
 /* Mode numbers */
 static const unsigned short ModeIndex_320x200[]      = {0x59, 0x41, 0x00, 0x4f};
index bc321dc57e92ebc1ceb4b70eadd1c2934c72fcf8..4f3a28699d3753ca7c48be541861ee6c1ca3950d 100644 (file)
 #include <linux/types.h>
 #include <asm/io.h>
 #include <linux/fb.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <video/fbcon.h>
-#endif
 #include "sis.h"
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <linux/sisfb.h>
-#else
 #include <video/sisfb.h>
 #endif
-#endif
 
 static const unsigned char SiS_YPbPrTable[3][64] = {
   {
index 09f5d758b6c02b79d3aab802698664c949f9de0d..c3884a29f4c5a15fd41679cb34363abfaf04b05c 100644 (file)
 #include <linux/types.h>
 #include <linux/fb.h>
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 int            sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr,
                        unsigned char modeno, unsigned char rateindex);
 int            sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
                        unsigned char rateindex, struct fb_var_screeninfo *var);
-#endif
 BOOLEAN                sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno,
                        int *htotal, int *vtotal, unsigned char rateindex);
 
@@ -49,7 +47,6 @@ extern BOOLEAN        SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *Mode
 extern void    SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata,
                        int xres, int yres, struct fb_var_screeninfo *var, BOOLEAN writeres);
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 int
 sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr, unsigned char modeno,
                        unsigned char rateindex)
@@ -177,7 +174,6 @@ sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
 
     return 1;
 }
-#endif /* Linux >= 2.5 */
 
 BOOLEAN
 sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno, int *htotal,
index f59568020eb220d7a720a10c73c87b3b5dadb66e..d048bd39961b173312be5fc0aac46d24c92185df 100644 (file)
 #define SIS315H
 #endif
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 #define SIS_LINUX_KERNEL_26
-#else
-#define SIS_LINUX_KERNEL_24
-#endif
 
 #if !defined(SIS300) && !defined(SIS315H)
 #warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set
index 3b7ce032e2ed6af47599e9336c01d37bdc864e8c..7addf91d2feab2068b65b627b52994ef3d42c3ac 100644 (file)
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/fb.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <linux/console.h>
-#endif
 #include <linux/ioport.h>
 #include <linux/types.h>
-
 #include <asm/io.h>
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb24.h>
-#include <video/fbcon-cfb32.h>
-#endif
-
 #include "sis.h"
 #include "sis_accel.h"
 
@@ -91,11 +79,9 @@ static const u8 sisPatALUConv[] =
     0xFF,       /* dest = 0xFF;         1,      GXset,          0xF */
 };
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)
 static const int myrops[] = {
        3, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
 };
-#endif
 
 /* 300 series ----------------------------------------------------- */
 #ifdef CONFIG_FB_SIS_300
@@ -315,8 +301,6 @@ void sisfb_syncaccel(struct sis_video_info *ivideo)
        }
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)  /* --------------- 2.5 --------------- */
-
 int fbcon_sis_sync(struct fb_info *info)
 {
        struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
@@ -438,13 +422,3 @@ void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 
        sisfb_syncaccel(ivideo);
 }
-
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)  /* -------------- 2.4 --------------- */
-
-#include "sisfb_accel_2_4.h"
-
-#endif /* KERNEL VERSION */
-
-
index 046e2c4a8e09cac082a317bf548826fe85b70b3e..30e03cdf6b85a18ba1ff43685995ee3edab9748d 100644 (file)
        MMIO_OUT32(ivideo->mmio_vbase, FIRE_TRIGGER, 0); \
        CmdQueLen -= 2;
 
-
 int  sisfb_initaccel(struct sis_video_info *ivideo);
 void sisfb_syncaccel(struct sis_video_info *ivideo);
 
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33)
-void fbcon_sis_bmove(struct display *p, int srcy, int srcx, int dsty,
-                       int dstx, int height, int width);
-void fbcon_sis_revc(struct display *p, int srcy, int srcx);
-void fbcon_sis_clear8(struct vc_data *conp, struct display *p, int srcy,
-                       int srcx, int height, int width);
-void fbcon_sis_clear16(struct vc_data *conp, struct display *p, int srcy,
-                       int srcx, int height, int width);
-void fbcon_sis_clear32(struct vc_data *conp, struct display *p, int srcy,
-                       int srcx, int height, int width);
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)
 int  fbcon_sis_sync(struct fb_info *info);
 void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
 void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area);
-#endif
 
 #endif
index 895ebda7d9e3547443785aa6e465589acd2457cf..baaf495a0a6dff7513fd1c054ec8551d59d09910 100644 (file)
@@ -35,9 +35,7 @@
 
 #include <linux/version.h>
 #include <linux/module.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 #include <linux/moduleparam.h>
-#endif
 #include <linux/kernel.h>
 #include <linux/smp_lock.h>
 #include <linux/spinlock.h>
@@ -58,9 +56,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <linux/vt_kern.h>
-#endif
 #include <linux/capability.h>
 #include <linux/fs.h>
 #include <linux/types.h>
 #include <asm/mtrr.h>
 #endif
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb24.h>
-#include <video/fbcon-cfb32.h>
-#endif
-
 #include "sis.h"
 #include "sis_main.h"
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3)
-#error "This version of sisfb requires at least 2.6.3"
-#endif
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#ifdef FBCON_HAS_CFB8
-extern struct display_switch fbcon_sis8;
-#endif
-#ifdef FBCON_HAS_CFB16
-extern struct display_switch fbcon_sis16;
-#endif
-#ifdef FBCON_HAS_CFB32
-extern struct display_switch fbcon_sis32;
-#endif
-#endif
-
 static void sisfb_handle_command(struct sis_video_info *ivideo,
                                 struct sisfb_cmd *sisfb_command);
 
@@ -114,17 +83,7 @@ sisfb_setdefaultparms(void)
        sisfb_max               = -1;
        sisfb_userom            = -1;
        sisfb_useoem            = -1;
-#ifdef MODULE
-       /* Module: "None" for 2.4, default mode for 2.5+ */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-       sisfb_mode_idx          = -1;
-#else
-       sisfb_mode_idx          = MODE_INDEX_NONE;
-#endif
-#else
-       /* Static: Default mode */
        sisfb_mode_idx          = -1;
-#endif
        sisfb_parm_rate         = -1;
        sisfb_crt1off           = 0;
        sisfb_forcecrt1         = -1;
@@ -142,10 +101,6 @@ sisfb_setdefaultparms(void)
        sisfb_tvxposoffset      = 0;
        sisfb_tvyposoffset      = 0;
        sisfb_nocrt2rate        = 0;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       sisfb_inverse           = 0;
-       sisfb_fontname[0]       = 0;
-#endif
 #if !defined(__i386__) && !defined(__x86_64__)
        sisfb_resetcard         = 0;
        sisfb_videoram          = 0;
@@ -162,14 +117,11 @@ sisfb_search_vesamode(unsigned int vesamode, BOOLEAN quiet)
        /* We don't know the hardware specs yet and there is no ivideo */
 
        if(vesamode == 0) {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-               sisfb_mode_idx = MODE_INDEX_NONE;
-#else
                if(!quiet)
                        printk(KERN_ERR "sisfb: Invalid mode. Using default.\n");
 
                sisfb_mode_idx = DEFAULT_MODE;
-#endif
+
                return;
        }
 
@@ -215,7 +167,6 @@ sisfb_search_mode(char *name, BOOLEAN quiet)
                return;
        }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
        if(!strnicmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) {
                if(!quiet)
                        printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
@@ -223,7 +174,7 @@ sisfb_search_mode(char *name, BOOLEAN quiet)
                sisfb_mode_idx = DEFAULT_MODE;
                return;
        }
-#endif
+
        if(strlen(name) <= 19) {
                strcpy(strbuf1, name);
                for(i = 0; i < strlen(strbuf1); i++) {
@@ -1315,20 +1266,7 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in
                ivideo->refresh_rate = 60;
        }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       if(ivideo->sisfb_thismonitor.datavalid) {
-               if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, ivideo->sisfb_mode_idx,
-                                ivideo->rate_idx, ivideo->refresh_rate)) {
-                       printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
-               }
-       }
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       if(((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) && isactive) {
-#else
        if(isactive) {
-#endif
                /* If acceleration to be used? Need to know
                 * before pre/post_set_mode()
                 */
@@ -1367,9 +1305,7 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in
                ivideo->current_linelength = ivideo->video_linelength;
                ivideo->current_pixclock = var->pixclock;
                ivideo->current_refresh_rate = ivideo->refresh_rate;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
                ivideo->sisfb_lastrates[ivideo->mode_no] = ivideo->refresh_rate;
-#endif
        }
 
        return 0;
@@ -1435,18 +1371,6 @@ sisfb_pan_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
        return 0;
 }
 
-/* ------------ FBDev related routines for 2.4 series ----------- */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-
-#include "sisfb_fbdev_2_4.h"
-
-#endif
-
-/* ------------ FBDev related routines for 2.6 series ----------- */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-
 static int
 sisfb_open(struct fb_info *info, int user)
 {
@@ -1744,8 +1668,6 @@ sisfb_blank(int blank, struct fb_info *info)
        return sisfb_myblank(ivideo, blank);
 }
 
-#endif
-
 /* ----------- FBDev related routines for all series ---------- */
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
@@ -1969,20 +1891,6 @@ sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
 
 /* ----------------  fb_ops structures ----------------- */
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-static struct fb_ops sisfb_ops = {
-       .owner          = THIS_MODULE,
-       .fb_get_fix     = sisfb_get_fix,
-       .fb_get_var     = sisfb_get_var,
-       .fb_set_var     = sisfb_set_var,
-       .fb_get_cmap    = sisfb_get_cmap,
-       .fb_set_cmap    = sisfb_set_cmap,
-       .fb_pan_display = sisfb_pan_display,
-       .fb_ioctl       = sisfb_ioctl
-};
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 static struct fb_ops sisfb_ops = {
        .owner          = THIS_MODULE,
        .fb_open        = sisfb_open,
@@ -2004,7 +1912,6 @@ static struct fb_ops sisfb_ops = {
 #endif
        .fb_ioctl       = sisfb_ioctl
 };
-#endif
 
 /* ---------------- Chip generation dependent routines ---------------- */
 
@@ -4100,16 +4007,6 @@ sisfb_setup(char *options)
                        sisfb_search_mode(this_opt + 5, FALSE);
                } else if(!strnicmp(this_opt, "vesa:", 5)) {
                        sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0), FALSE);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-               } else if(!strnicmp(this_opt, "inverse", 7)) {
-                       sisfb_inverse = 1;
-                       /* fb_invert_cmaps(); */
-               } else if(!strnicmp(this_opt, "font:", 5)) {
-                       if(strlen(this_opt + 5) < 40) {
-                          strncpy(sisfb_fontname, this_opt + 5, sizeof(sisfb_fontname) - 1);
-                          sisfb_fontname[sizeof(sisfb_fontname) - 1] = '\0';
-                       }
-#endif
                } else if(!strnicmp(this_opt, "rate:", 5)) {
                        sisfb_parm_rate = simple_strtoul(this_opt + 5, NULL, 0);
                } else if(!strnicmp(this_opt, "forcecrt1:", 10)) {
@@ -5870,17 +5767,9 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        if(sisfb_off)
                return -ENXIO;
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,3))
        sis_fb_info = framebuffer_alloc(sizeof(*ivideo), &pdev->dev);
        if(!sis_fb_info)
                return -ENOMEM;
-#else
-       sis_fb_info = kmalloc(sizeof(*sis_fb_info) + sizeof(*ivideo), GFP_KERNEL);
-       if(!sis_fb_info)
-               return -ENOMEM;
-       memset(sis_fb_info, 0, sizeof(*sis_fb_info) + sizeof(*ivideo));
-       sis_fb_info->par = ((char *)sis_fb_info + sizeof(*sis_fb_info));
-#endif
 
        ivideo = (struct sis_video_info *)sis_fb_info->par;
        ivideo->memyselfandi = sis_fb_info;
@@ -5970,10 +5859,6 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        ivideo->tvxpos = sisfb_tvxposoffset;
        ivideo->tvypos = sisfb_tvyposoffset;
        ivideo->sisfb_nocrt2rate = sisfb_nocrt2rate;
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
-       ivideo->sisfb_inverse = sisfb_inverse;
-#endif
-
        ivideo->refresh_rate = 0;
        if(ivideo->sisfb_parm_rate != -1) {
                ivideo->refresh_rate = ivideo->sisfb_parm_rate;
@@ -6049,10 +5934,6 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                }
        }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       strcpy(sis_fb_info->modename, ivideo->myid);
-#endif
-
        ivideo->SiS_Pr.ChipType = ivideo->chip;
 
        ivideo->SiS_Pr.ivideo = (void *)ivideo;
@@ -6134,20 +6015,6 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 #endif
        }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#ifdef MODULE
-       if((reg & 0x80) && (reg != 0xff)) {
-               if((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni])
-                                                                       != 0xFF) {
-                       printk(KERN_INFO "sisfb: Cannot initialize display mode, "
-                                        "X server is active\n");
-                       ret = -EBUSY;
-                       goto error_4;
-               }
-       }
-#endif
-#endif
-
        /* Search and copy ROM image */
        ivideo->bios_abase = NULL;
        ivideo->SiS_Pr.VirtualRomBase = NULL;
@@ -6281,9 +6148,6 @@ error_0:  iounmap(ivideo->video_vbase);
 error_1:       release_mem_region(ivideo->video_base, ivideo->video_size);
 error_2:       release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
 error_3:       vfree(ivideo->bios_abase);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-error_4:
-#endif
                if(ivideo->lpcdev)
                        SIS_PCI_PUT_DEVICE(ivideo->lpcdev);
                if(ivideo->nbridge)
@@ -6586,7 +6450,6 @@ error_4:
                sis_fb_info->fix = ivideo->sisfb_fix;
                sis_fb_info->screen_base = ivideo->video_vbase + ivideo->video_offset;
                sis_fb_info->fbops = &sisfb_ops;
-
                sisfb_get_fix(&sis_fb_info->fix, -1, sis_fb_info);
                sis_fb_info->pseudo_palette = ivideo->pseudo_palette;
 
@@ -6603,10 +6466,6 @@ error_4:
                }
 #endif
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-               vc_resize_con(1, 1, 0);
-#endif
-
                if(register_framebuffer(sis_fb_info) < 0) {
                        printk(KERN_ERR "sisfb: Fatal error: Failed to register framebuffer\n");
                        ret = -EINVAL;
@@ -6653,12 +6512,7 @@ error_4:
 
 
                printk(KERN_INFO "fb%d: %s frame buffer device version %d.%d.%d\n",
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-                       GET_FB_IDX(sis_fb_info->node),
-#else
-                       sis_fb_info->node,
-#endif
-                       ivideo->myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
+                       sis_fb_info->node, ivideo->myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
 
                printk(KERN_INFO "sisfb: Copyright (C) 2001-2005 Thomas Winischhofer\n");
 
@@ -6732,11 +6586,7 @@ static void __devexit sisfb_remove(struct pci_dev *pdev)
        /* Unregister the framebuffer */
        if(ivideo->registered) {
                unregister_framebuffer(sis_fb_info);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,3))
                framebuffer_release(sis_fb_info);
-#else
-               kfree(sis_fb_info);
-#endif
        }
 
        /* OK, our ivideo is gone for good from here. */
@@ -6762,7 +6612,6 @@ static struct pci_driver sisfb_driver = {
 
 SISINITSTATIC int __init sisfb_init(void)
 {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
 #ifndef MODULE
        char *options = NULL;
 
@@ -6770,16 +6619,13 @@ SISINITSTATIC int __init sisfb_init(void)
                return -ENODEV;
 
        sisfb_setup(options);
-#endif
 #endif
        return pci_register_driver(&sisfb_driver);
 }
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
 #ifndef MODULE
 module_init(sisfb_init);
 #endif
-#endif
 
 /*****************************************************/
 /*                      MODULE                       */
@@ -6799,9 +6645,6 @@ static int                pdc1 = -1;
 static int             noaccel = -1;
 static int             noypan  = -1;
 static int             nomax = -1;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-static int             inverse = 0;
-#endif
 static int             userom = -1;
 static int             useoem = -1;
 static char            *tvstandard = NULL;
@@ -6861,10 +6704,6 @@ static int __init sisfb_init_module(void)
        else if(nomax == 0)
                sisfb_max = 1;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       if(inverse) sisfb_inverse = 1;
-#endif
-
        if(mem)
                sisfb_parm_mem = mem;
 
@@ -6913,35 +6752,6 @@ MODULE_DESCRIPTION("SiS 300/540/630/730/315/55x/65x/661/74x/330/76x/34x, XGI V3X
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>, Others");
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-MODULE_PARM(mem, "i");
-MODULE_PARM(noaccel, "i");
-MODULE_PARM(noypan, "i");
-MODULE_PARM(nomax, "i");
-MODULE_PARM(userom, "i");
-MODULE_PARM(useoem, "i");
-MODULE_PARM(mode, "s");
-MODULE_PARM(vesa, "i");
-MODULE_PARM(rate, "i");
-MODULE_PARM(forcecrt1, "i");
-MODULE_PARM(forcecrt2type, "s");
-MODULE_PARM(scalelcd, "i");
-MODULE_PARM(pdc, "i");
-MODULE_PARM(pdc1, "i");
-MODULE_PARM(specialtiming, "s");
-MODULE_PARM(lvdshl, "i");
-MODULE_PARM(tvstandard, "s");
-MODULE_PARM(tvxposoffset, "i");
-MODULE_PARM(tvyposoffset, "i");
-MODULE_PARM(nocrt2rate, "i");
-MODULE_PARM(inverse, "i");
-#if !defined(__i386__) && !defined(__x86_64__)
-MODULE_PARM(resetcard, "i");
-MODULE_PARM(videoram, "i");
-#endif
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 module_param(mem, int, 0);
 module_param(noaccel, int, 0);
 module_param(noypan, int, 0);
@@ -6966,18 +6776,7 @@ module_param(nocrt2rate, int, 0);
 module_param(resetcard, int, 0);
 module_param(videoram, int, 0);
 #endif
-#endif
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-MODULE_PARM_DESC(mem,
-       "\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
-         "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
-         "on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
-         "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
-         "otherwise at 12288KB. On 315/330/340 series, the heap size is 32KB by default.\n"
-         "The value is to be specified without 'KB' and must match the MaxXFBMem setting\n"
-         "for XFree86 4.x/X.org 6.7 and later.\n");
-#else
 MODULE_PARM_DESC(mem,
        "\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
          "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
@@ -6985,7 +6784,6 @@ MODULE_PARM_DESC(mem,
          "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
          "otherwise at 12288KB. On 315/330/340 series, the heap size is 32KB by default.\n"
          "The value is to be specified without 'KB'.\n");
-#endif
 
 MODULE_PARM_DESC(noaccel,
        "\nIf set to anything other than 0, 2D acceleration will be disabled.\n"
@@ -7002,23 +6800,6 @@ MODULE_PARM_DESC(nomax,
          "enable the user to positively specify a virtual Y size of the screen using\n"
          "fbset. (default: 0)\n");
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-MODULE_PARM_DESC(mode,
-       "\nSelects the desired display mode in the format [X]x[Y]x[Depth], eg.\n"
-         "1024x768x16. Other formats supported include XxY-Depth and\n"
-         "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
-         "number, it will be interpreted as a VESA mode number. (default: none if\n"
-         "sisfb is a module; this leaves the console untouched and the driver will\n"
-         "only do the video memory management for eg. DRM/DRI; 800x600x8 if sisfb\n"
-         "is in the kernel)\n");
-MODULE_PARM_DESC(vesa,
-       "\nSelects the desired display mode by VESA defined mode number, eg. 0x117\n"
-         "(default: 0x0000 if sisfb is a module; this leaves the console untouched\n"
-         "and the driver will only do the video memory management for eg. DRM/DRI;\n"
-         "0x0103 if sisfb is in the kernel)\n");
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 MODULE_PARM_DESC(mode,
        "\nSelects the desired default display mode in the format XxYxDepth,\n"
         "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
@@ -7028,7 +6809,6 @@ MODULE_PARM_DESC(mode,
 MODULE_PARM_DESC(vesa,
        "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
         "0x117 (default: 0x0103)\n");
-#endif
 
 MODULE_PARM_DESC(rate,
        "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
@@ -7094,12 +6874,6 @@ MODULE_PARM_DESC(nocrt2rate,
        "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
          "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-MODULE_PARM_DESC(inverse,
-       "\nSetting this to anything but 0 should invert the display colors, but this\n"
-         "does not seem to work. (default: 0)\n");
-#endif
-
 #if !defined(__i386__) && !defined(__x86_64__)
 #ifdef CONFIG_FB_SIS_300
 MODULE_PARM_DESC(resetcard,
index 70b6df371b8e7f72231c91c9bbc32efb9c1fdb28..88e4f1e414706cb444568c6adc390f4f5131cdd5 100644 (file)
@@ -67,15 +67,7 @@ static int sisfb_ypan = -1;
 static int sisfb_max = -1;
 static int sisfb_userom = 1;
 static int sisfb_useoem = -1;
-#ifdef MODULE
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-static int sisfb_mode_idx = -1;
-#else
-static int sisfb_mode_idx = MODE_INDEX_NONE;  /* Don't use a mode by default if we are a module */
-#endif
-#else
 static int sisfb_mode_idx = -1;               /* Use a default mode if we are inside the kernel */
-#endif
 static int sisfb_parm_rate = -1;
 static int sisfb_crt1off = 0;
 static int sisfb_forcecrt1 = -1;
@@ -93,10 +85,6 @@ static int sisfb_tvstd  = -1;
 static int sisfb_tvxposoffset = 0;
 static int sisfb_tvyposoffset = 0;
 static int sisfb_nocrt2rate = 0;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-static int  sisfb_inverse = 0;
-static char sisfb_fontname[40];
-#endif
 #if !defined(__i386__) && !defined(__x86_64__)
 static int sisfb_resetcard = 0;
 static int sisfb_videoram = 0;
@@ -687,54 +675,8 @@ SISINITSTATIC int sisfb_init(void);
 static int     sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
                                struct fb_info *info);
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-static int     sisfb_get_fix(struct fb_fix_screeninfo *fix,
-                               int con,
-                               struct fb_info *info);
-static int     sisfb_get_var(struct fb_var_screeninfo *var,
-                               int con,
-                               struct fb_info *info);
-static int     sisfb_set_var(struct fb_var_screeninfo *var,
-                               int con,
-                               struct fb_info *info);
-static void    sisfb_crtc_to_var(struct sis_video_info *ivideo,
-                               struct fb_var_screeninfo *var);
-static int     sisfb_get_cmap(struct fb_cmap *cmap,
-                               int kspc,
-                               int con,
-                               struct fb_info *info);
-static int     sisfb_set_cmap(struct fb_cmap *cmap,
-                               int kspc,
-                               int con,
-                               struct fb_info *info);
-static int     sisfb_update_var(int con,
-                               struct fb_info *info);
-static int     sisfb_switch(int con,
-                            struct fb_info *info);
-static void    sisfb_blank(int blank,
-                               struct fb_info *info);
-static void    sisfb_set_disp(int con,
-                               struct fb_var_screeninfo *var,
-                               struct fb_info *info);
-static int     sis_getcolreg(unsigned regno, unsigned *red, unsigned *green,
-                               unsigned *blue, unsigned *transp,
-                               struct fb_info *fb_info);
-static void    sisfb_do_install_cmap(int con,
-                               struct fb_info *info);
-static int     sisfb_ioctl(struct inode *inode, struct file *file,
-                               unsigned int cmd, unsigned long arg, int con,
-                               struct fb_info *info);
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
 static int     sisfb_ioctl(struct fb_info *info, unsigned int cmd,
                            unsigned long arg);
-#else
-static int     sisfb_ioctl(struct inode *inode, struct file *file,
-                               unsigned int cmd, unsigned long arg,
-                               struct fb_info *info);
-#endif
 static int     sisfb_set_par(struct fb_info *info);
 static int     sisfb_blank(int blank,
                                struct fb_info *info);
@@ -743,7 +685,6 @@ extern void fbcon_sis_fillrect(struct fb_info *info,
 extern void    fbcon_sis_copyarea(struct fb_info *info,
                                const struct fb_copyarea *area);
 extern int     fbcon_sis_sync(struct fb_info *info);
-#endif
 
 /* Internal 2D accelerator functions */
 extern int     sisfb_initaccel(struct sis_video_info *ivideo);
@@ -811,16 +752,10 @@ extern BOOLEAN            SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr);
 
 extern BOOLEAN         sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno,
                                int *htotal, int *vtotal, unsigned char rateindex);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 extern int             sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr,
                                unsigned char modeno, unsigned char rateindex);
 extern int             sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
                                unsigned char rateindex, struct fb_var_screeninfo *var);
-#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-extern void            SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres,
-                               int yres, struct fb_var_screeninfo *var, BOOLEAN writeres);
-#endif
 
 /* Chrontel TV, DDC and DPMS functions */
 extern unsigned short  SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg);
index 831b9f42264bb8590d1cebf3c978ac8b4114a5f0..05d08b7889a1aca636b516b032341cbade9582a6 100644 (file)
@@ -73,12 +73,10 @@ typedef unsigned int BOOLEAN;
 
 #ifdef SIS_LINUX_KERNEL
 typedef unsigned long SISIOADDRESS;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
 #include <linux/types.h>  /* Need __iomem */
 #undef SISIOMEMTYPE
 #define SISIOMEMTYPE __iomem
 #endif
-#endif
 
 #ifdef SIS_XORG_XF86
 #if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,0,0,0)
index dad54e73147b4d68420fb5c189889c94213f34bd..711cb11d6eb34e6223d2eb67463de2073492d909 100644 (file)
  *     (port driver to new frambuffer infrastructure)
  * 01/2003 Helge Deller    <deller@gmx.de>
  *     (initial work on fb hardware acceleration for voodoo2)
- *
+ * 08/2006 Alan Cox       <alan@redhat.com>
+ *     Remove never finished and bogus 24/32bit support
+ *     Clean up macro abuse
+ *     Minor tidying for format.
  */
 
 /*
@@ -40,6 +43,7 @@
        through the fifo. warning: issuing a nop command seems to need pci_fifo
 -FIXME: in case of failure in the init sequence, be sure we return to a safe
         state.
+- FIXME: Use accelerator for 2D scroll
 -FIXME: 4MB boards have banked memory (FbiInit2 bits 1 & 20)
  */
 
@@ -67,9 +71,6 @@
 
 #undef SST_DEBUG
 
-/* enable 24/32 bpp functions ? (completely untested!) */
-#undef EN_24_32_BPP
-
 /*
   Default video mode .
   0 800x600@60  took from glide
@@ -377,7 +378,11 @@ static void sstfb_clear_screen(struct fb_info *info)
  *      sstfb_check_var - Optional function.  Validates a var passed in.
  *      @var: frame buffer variable screen structure
  *      @info: frame buffer structure that represents a single frame buffer
+ *
+ *     Limit to the abilities of a single chip as SLI is not supported
+ *     by this driver.
  */
+
 static int sstfb_check_var(struct fb_var_screeninfo *var,
                struct fb_info *info)
 {
@@ -390,7 +395,7 @@ static int sstfb_check_var(struct fb_var_screeninfo *var,
        unsigned int freq;
 
        if (sst_calc_pll(PICOS2KHZ(var->pixclock), &freq, &par->pll)) {
-               eprintk("Pixclock at %ld KHZ out of range\n",
+               printk(KERN_ERR "sstfb: Pixclock at %ld KHZ out of range\n",
                                PICOS2KHZ(var->pixclock));
                return -EINVAL;
        }
@@ -409,27 +414,15 @@ static int sstfb_check_var(struct fb_var_screeninfo *var,
        case 0 ... 16 :
                var->bits_per_pixel = 16;
                break;
-#ifdef EN_24_32_BPP
-       case 17 ... 24 :
-               var->bits_per_pixel = 24;
-               break;
-       case 25 ... 32 :
-               var->bits_per_pixel = 32;
-               break;
-#endif
        default :
-               eprintk("Unsupported bpp %d\n", var->bits_per_pixel);
+               printk(KERN_ERR "sstfb: Unsupported bpp %d\n", var->bits_per_pixel);
                return -EINVAL;
        }
        
        /* validity tests */
-       if ((var->xres <= 1) || (yDim <= 0 )
-          || (var->hsync_len <= 1)
-          || (hSyncOff <= 1)
-          || (var->left_margin <= 2)
-          || (vSyncOn <= 0)
-          || (vSyncOff <= 0)
-          || (vBackPorch <= 0)) {
+       if (var->xres <= 1 || yDim <= 0 || var->hsync_len <= 1  ||
+           hSyncOff <= 1  || var->left_margin <= 2  || vSyncOn <= 0 ||
+           vSyncOff <= 0 || vBackPorch <= 0) {
                return -EINVAL;
        }
 
@@ -437,21 +430,17 @@ static int sstfb_check_var(struct fb_var_screeninfo *var,
                /* Voodoo 2 limits */
                tiles_in_X = (var->xres + 63 ) / 64 * 2;                
 
-               if (((var->xres - 1) >= POW2(11)) || (yDim >= POW2(11))) {
-                       eprintk("Unsupported resolution %dx%d\n",
+               if (var->xres  > POW2(11) || yDim >= POW2(11)) {
+                       printk(KERN_ERR "sstfb: Unsupported resolution %dx%d\n",
                                 var->xres, var->yres);
                        return -EINVAL;
                }
 
-               if (((var->hsync_len-1) >= POW2(9))
-                  || ((hSyncOff-1) >= POW2(11))
-                  || ((var->left_margin - 2) >= POW2(9))
-                  || (vSyncOn >= POW2(13))
-                  || (vSyncOff >= POW2(13))
-                  || (vBackPorch >= POW2(9))
-                  || (tiles_in_X >= POW2(6))
-                  || (tiles_in_X <= 0)) {
-                       eprintk("Unsupported Timings\n");
+               if (var->hsync_len > POW2(9) || hSyncOff > POW2(11) ||
+                   var->left_margin - 2 >= POW2(9) || vSyncOn >= POW2(13) ||
+                   vSyncOff >= POW2(13) || vBackPorch >= POW2(9) ||
+                   tiles_in_X >= POW2(6) || tiles_in_X <= 0) {
+                       printk(KERN_ERR "sstfb: Unsupported timings\n");
                        return -EINVAL;
                }
        } else {
@@ -459,24 +448,20 @@ static int sstfb_check_var(struct fb_var_screeninfo *var,
                tiles_in_X = (var->xres + 63 ) / 64;
 
                if (var->vmode) {
-                       eprintk("Interlace/Doublescan not supported %#x\n",
+                       printk(KERN_ERR "sstfb: Interlace/doublescan not supported %#x\n",
                                var->vmode);
                        return -EINVAL;
                }
-               if (((var->xres - 1) >= POW2(10)) || (var->yres >= POW2(10))) {
-                       eprintk("Unsupported resolution %dx%d\n",
+               if (var->xres > POW2(10) || var->yres >= POW2(10)) {
+                       printk(KERN_ERR "sstfb: Unsupported resolution %dx%d\n",
                                 var->xres, var->yres);
                        return -EINVAL;
                }
-               if (((var->hsync_len - 1) >= POW2(8))
-                  || ((hSyncOff-1) >= POW2(10))
-                  || ((var->left_margin - 2) >= POW2(8))
-                  || (vSyncOn >= POW2(12))
-                  || (vSyncOff >= POW2(12))
-                  || (vBackPorch >= POW2(8))
-                  || (tiles_in_X >= POW2(4))
-                  || (tiles_in_X <= 0)) {
-                       eprintk("Unsupported Timings\n");
+               if (var->hsync_len > POW2(8) || hSyncOff - 1 > POW2(10) ||
+                   var->left_margin - 2 >= POW2(8) || vSyncOn >= POW2(12) ||
+                   vSyncOff >= POW2(12) || vBackPorch >= POW2(8) ||
+                   tiles_in_X >= POW2(4) || tiles_in_X <= 0) {
+                       printk(KERN_ERR "sstfb: Unsupported timings\n");
                        return -EINVAL;
                }
        }
@@ -486,8 +471,8 @@ static int sstfb_check_var(struct fb_var_screeninfo *var,
        real_length = tiles_in_X  * (IS_VOODOO2(par) ? 32 : 64 )
                      * ((var->bits_per_pixel == 16) ? 2 : 4);
 
-       if ((real_length * yDim) > info->fix.smem_len) {
-               eprintk("Not enough video memory\n");
+       if (real_length * yDim > info->fix.smem_len) {
+               printk(KERN_ERR "sstfb: Not enough video memory\n");
                return -ENOMEM;
        }
 
@@ -515,20 +500,6 @@ static int sstfb_check_var(struct fb_var_screeninfo *var,
                var->blue.offset   = 0;
                var->transp.offset = 0;
                break;
-#ifdef EN_24_32_BPP
-       case 24:        /* RGB 888 LfbMode 4 */
-       case 32:        /* ARGB 8888 LfbMode 5 */
-               var->red.length    = 8;
-               var->green.length  = 8;
-               var->blue.length   = 8;
-               var->transp.length = 0;
-
-               var->red.offset    = 16;
-               var->green.offset  = 8;
-               var->blue.offset   = 0;
-               var->transp.offset = 0; /* in 24bpp we fake a 32 bpp mode */
-               break;
-#endif
        default:
                return -EINVAL;
        }
@@ -653,13 +624,6 @@ static int sstfb_set_par(struct fb_info *info)
        case 16:
                fbiinit1 |=  SEL_SOURCE_VCLK_2X_SEL;
                break;
-#ifdef EN_24_32_BPP
-       case 24:
-       case 32:
-               /* sst_set_bits(FBIINIT1, SEL_SOURCE_VCLK_2X_DIV2 | EN_24BPP);*/
-               fbiinit1 |= SEL_SOURCE_VCLK_2X_SEL | EN_24BPP;
-               break;
-#endif
        default:
                return -EINVAL;
        }
@@ -690,14 +654,6 @@ static int sstfb_set_par(struct fb_info *info)
        case 16:
                lfbmode = LFB_565;
                break;
-#ifdef EN_24_32_BPP
-       case 24:
-               lfbmode = LFB_888;
-               break;
-       case 32:
-               lfbmode = LFB_8888;
-               break;
-#endif
        default:
                return -EINVAL;
        }
@@ -789,8 +745,7 @@ static int sstfb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
                        return -EFAULT;
                if (val > info->fix.smem_len)
                        val = info->fix.smem_len;
-               printk("filling %#x \n", val);
-               for (p=0 ; p<val; p+=2)
+               for (p = 0 ; p < val; p += 2)
                        writew(p >> 6, info->screen_base + p);
                return 0;
                
@@ -802,13 +757,10 @@ static int sstfb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
                pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
                                       tmp | PCI_EN_INIT_WR );
                fbiinit0 = sst_read (FBIINIT0);
-               if (val) {
+               if (val)
                        sst_write(FBIINIT0, fbiinit0 & ~EN_VGA_PASSTHROUGH);
-                       iprintk("Disabling VGA pass-through\n");
-               } else {
+               else
                        sst_write(FBIINIT0, fbiinit0 | EN_VGA_PASSTHROUGH);
-                       iprintk("Enabling VGA pass-through\n");
-               }
                pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, tmp);
                return 0;
                
@@ -884,9 +836,9 @@ static int __devinit sst_get_memsize(struct fb_info *info, __u32 *memsize)
        u8 __iomem *fbbase_virt = info->screen_base;
 
        /* force memsize */
-       if ((mem >= 1 ) &&  (mem <= 4)) {
+       if (mem >= 1  && mem <= 4) {
                *memsize = (mem * 0x100000);
-               iprintk("supplied memsize: %#x\n", *memsize);
+               printk(KERN_INFO "supplied memsize: %#x\n", *memsize);
                return 1;
        }
 
@@ -927,7 +879,7 @@ static int __devinit sst_detect_att(struct fb_info *info)
        struct sstfb_par *par = info->par;
        int i, mir, dir;
 
-       for (i=0; i<3; i++) {
+       for (i = 0; i < 3; i++) {
                sst_dac_write(DACREG_WMA, 0);   /* backdoor */
                sst_dac_read(DACREG_RMR);       /* read 4 times RMR */
                sst_dac_read(DACREG_RMR);
@@ -940,7 +892,7 @@ static int __devinit sst_detect_att(struct fb_info *info)
                /*the 7th, device ID register */
                dir = sst_dac_read(DACREG_RMR);
                f_ddprintk("mir: %#x, dir: %#x\n", mir, dir);
-               if ((mir == DACREG_MIR_ATT ) && (dir == DACREG_DIR_ATT)) {
+               if (mir == DACREG_MIR_ATT && dir == DACREG_DIR_ATT) {
                        return 1;
                }
        }
@@ -1134,12 +1086,6 @@ static void sst_set_vidmod_att_ti(struct fb_info *info, const int bpp)
        case 16:
                sst_dac_write(DACREG_RMR, (cr0 & 0x0f) | DACREG_CR0_16BPP);
                break;
-#ifdef EN_24_32_BPP
-       case 24:
-       case 32:
-               sst_dac_write(DACREG_RMR, (cr0 & 0x0f) | DACREG_CR0_24BPP);
-               break;
-#endif
        default:
                dprintk("%s: bad depth '%u'\n", __FUNCTION__, bpp);
                break;
@@ -1154,12 +1100,6 @@ static void sst_set_vidmod_ics(struct fb_info *info, const int bpp)
        case 16:
                sst_dac_write(DACREG_ICS_CMD, DACREG_ICS_CMD_16BPP);
                break;
-#ifdef EN_24_32_BPP
-       case 24:
-       case 32:
-               sst_dac_write(DACREG_ICS_CMD, DACREG_ICS_CMD_24BPP);
-               break;
-#endif
        default:
                dprintk("%s: bad depth '%u'\n", __FUNCTION__, bpp);
                break;
@@ -1250,7 +1190,7 @@ static int __devinit sst_init(struct fb_info *info, struct sstfb_par *par)
                                PCI_EN_INIT_WR | PCI_REMAP_DAC );
        /* detect dac type */
        if (!sst_detect_dactype(info, par)) {
-               eprintk("Unknown dac type\n");
+               printk(KERN_ERR "sstfb: unknown dac type.\n");
                //FIXME watch it: we are not in a safe state, bad bad bad.
                return 0;
        }
@@ -1258,10 +1198,10 @@ static int __devinit sst_init(struct fb_info *info, struct sstfb_par *par)
        /* set graphic clock */
        par->gfx_clock = spec->default_gfx_clock;
        if ((gfxclk >10 ) && (gfxclk < spec->max_gfxclk)) {
-               iprintk("Using supplied graphic freq : %dMHz\n", gfxclk);
+               printk(KERN_INFO "sstfb: Using supplied graphic freq : %dMHz\n", gfxclk);
                 par->gfx_clock = gfxclk *1000;
        } else if (gfxclk) {
-               wprintk ("%dMhz is way out of spec! Using default\n", gfxclk);
+               printk(KERN_WARNING "sstfb: %dMhz is way out of spec! Using default\n", gfxclk);
        }
 
        sst_calc_pll(par->gfx_clock, &Fout, &gfx_timings);
@@ -1396,7 +1336,7 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
 
        /* Enable device in PCI config. */
        if ((err=pci_enable_device(pdev))) {
-               eprintk("cannot enable device\n");
+               printk(KERN_ERR "cannot enable device\n");
                return err;
        }
 
@@ -1422,39 +1362,39 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
        fix->smem_start = fix->mmio_start + 0x400000;
 
        if (!request_mem_region(fix->mmio_start, fix->mmio_len, "sstfb MMIO")) {
-               eprintk("cannot reserve mmio memory\n");
+               printk(KERN_ERR "sstfb: cannot reserve mmio memory\n");
                goto fail_mmio_mem;
        }
 
        if (!request_mem_region(fix->smem_start, 0x400000,"sstfb FB")) {
-               eprintk("cannot reserve fb memory\n");
+               printk(KERN_ERR "sstfb: cannot reserve fb memory\n");
                goto fail_fb_mem;
        }
 
        par->mmio_vbase = ioremap_nocache(fix->mmio_start,
                                        fix->mmio_len);
        if (!par->mmio_vbase) {
-               eprintk("cannot remap register area %#lx\n",
+               printk(KERN_ERR "sstfb: cannot remap register area %#lx\n",
                        fix->mmio_start);
                goto fail_mmio_remap;
        }
        info->screen_base = ioremap_nocache(fix->smem_start, 0x400000);
        if (!info->screen_base) {
-               eprintk("cannot remap framebuffer %#lx\n",
+               printk(KERN_ERR "sstfb: cannot remap framebuffer %#lx\n",
                        fix->smem_start);
                goto fail_fb_remap;
        }
 
        if (!sst_init(info, par)) {
-               eprintk("Init failed\n");
+               printk(KERN_ERR "sstfb: Init failed\n");
                goto fail;
        }
        sst_get_memsize(info, &fix->smem_len);
        strlcpy(fix->id, spec->name, sizeof(fix->id));
 
-       iprintk("%s (revision %d) with %s dac\n",
+       printk(KERN_INFO "%s (revision %d) with %s dac\n",
                fix->id, par->revision, par->dac_sw.name);
-       iprintk("framebuffer at %#lx, mapped to 0x%p, size %dMB\n",
+       printk(KERN_INFO "framebuffer at %#lx, mapped to 0x%p, size %dMB\n",
                fix->smem_start, info->screen_base,
                fix->smem_len >> 20);
 
@@ -1471,24 +1411,25 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
        fix->accel      = FB_ACCEL_NONE;  /* FIXME */
        /*
         * According to the specs, the linelength must be of 1024 *pixels*
-        * and the 24bpp mode is in fact a 32 bpp mode.
+        * and the 24bpp mode is in fact a 32 bpp mode (and both are in
+        * fact dithered to 16bit).
         */
        fix->line_length = 2048; /* default value, for 24 or 32bit: 4096 */
        
        if ( mode_option &&
             fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 16)) {
-               eprintk("can't set supplied video mode. Using default\n");
+               printk(KERN_ERR "sstfb: can't set supplied video mode. Using default\n");
                info->var = sstfb_default;
        } else
                info->var = sstfb_default;
 
        if (sstfb_check_var(&info->var, info)) {
-               eprintk("invalid default video mode.\n");
+               printk(KERN_ERR "sstfb: invalid default video mode.\n");
                goto fail;
        }
 
        if (sstfb_set_par(info)) {
-               eprintk("can't set default video mode.\n");
+               printk(KERN_ERR "sstfb: can't set default video mode.\n");
                goto fail;
        }
        
@@ -1497,7 +1438,7 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
        /* register fb */
        info->device = &pdev->dev;
        if (register_framebuffer(info) < 0) {
-               eprintk("can't register framebuffer.\n");
+               printk(KERN_ERR "sstfb: can't register framebuffer.\n");
                goto fail;
        }
 
@@ -1711,4 +1652,3 @@ module_param(gfxclk, int, 0);
 MODULE_PARM_DESC(gfxclk, "Force graphic chip frequency in MHz. DANGEROUS. (default=auto)");
 module_param(slowpci, bool, 0);
 MODULE_PARM_DESC(slowpci, "Uses slow PCI settings (0 or 1) (default=0)");
-
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 fa64867d6ed64feb339a0b37d97a929dca723ca3..599de54451af61c3297e4d18b068e5799b36e4b2 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.
@@ -996,6 +996,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
@@ -1033,7 +1045,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.
@@ -1091,7 +1103,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/>).
@@ -1261,7 +1273,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
@@ -1366,7 +1378,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
@@ -1951,7 +1963,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 215f70378177668dcd0e87437c02e3d61f0221e2..df614eacee8620c07b15bb3080f65405e4674392 100644 (file)
@@ -76,6 +76,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 2fc99877cb0d1b55c74329a40cd23f2eaae91e13..cf8a2cb2850563d9c9d19741dd2c3b12d367b01a 100644 (file)
@@ -30,7 +30,7 @@ static int afs_dir_readdir(struct file *file, void *dirent, filldir_t filldir);
 static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd);
 static int afs_d_delete(struct dentry *dentry);
 static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen,
-                                 loff_t fpos, ino_t ino, unsigned dtype);
+                                 loff_t fpos, u64 ino, unsigned dtype);
 
 const struct file_operations afs_dir_file_operations = {
        .open           = afs_dir_open,
@@ -409,7 +409,7 @@ static int afs_dir_readdir(struct file *file, void *cookie, filldir_t filldir)
  *   uniquifier through dtype
  */
 static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen,
-                                 loff_t fpos, ino_t ino, unsigned dtype)
+                                 loff_t fpos, u64 ino, unsigned dtype)
 {
        struct afs_dir_lookup_cookie *cookie = _cookie;
 
index 2e0d1505ee367c4cd7d3169c9b7a08b8fedaa930..94766599db00d3ca530eb37da388e1e63b900d35 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -675,7 +675,7 @@ static ssize_t aio_run_iocb(struct kiocb *iocb)
        }
 
        if (!(iocb->ki_retried & 0xff)) {
-               pr_debug("%ld retry: %d of %d\n", iocb->ki_retried,
+               pr_debug("%ld retry: %zd of %zd\n", iocb->ki_retried,
                        iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes);
        }
 
@@ -1008,7 +1008,7 @@ int fastcall aio_complete(struct kiocb *iocb, long res, long res2)
 
        pr_debug("added to ring %p at [%lu]\n", iocb, tail);
 
-       pr_debug("%ld retries: %d of %d\n", iocb->ki_retried,
+       pr_debug("%ld retries: %zd of %zd\n", iocb->ki_retried,
                iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes);
 put_rq:
        /* everything turned out well, dispose of the aiocb. */
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 32b5d625ce9c7c311835139eea61e8b98896a7b1..5bcdaaf4eae082f26adb82f0d2fe843dd4fc6ad1 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/personality.h>
 #include <linux/init.h>
 
+#include <asm/a.out.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 
@@ -194,6 +195,7 @@ load_som_binary(struct linux_binprm * bprm, struct pt_regs * regs)
        unsigned long som_entry;
        struct som_hdr *som_ex;
        struct som_exec_auxhdr *hpuxhdr;
+       struct files_struct *files;
 
        /* Get the exec-header */
        som_ex = (struct som_hdr *) bprm->buf;
@@ -208,15 +210,27 @@ load_som_binary(struct linux_binprm * bprm, struct pt_regs * regs)
        size = som_ex->aux_header_size;
        if (size > SOM_PAGESIZE)
                goto out;
-       hpuxhdr = (struct som_exec_auxhdr *) kmalloc(size, GFP_KERNEL);
+       hpuxhdr = kmalloc(size, GFP_KERNEL);
        if (!hpuxhdr)
                goto out;
 
        retval = kernel_read(bprm->file, som_ex->aux_header_location,
                        (char *) hpuxhdr, size);
+       if (retval != size) {
+               if (retval >= 0)
+                       retval = -EIO;
+               goto out_free;
+       }
+
+       files = current->files; /* Refcounted so ok */
+       retval = unshare_files();
        if (retval < 0)
                goto out_free;
-#error "Fix security hole before enabling me"
+       if (files == current->files) {
+               put_files_struct(files);
+               files = NULL;
+       }
+
        retval = get_unused_fd();
        if (retval < 0)
                goto out_free;
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 0e9ba0b9d71eb008138eab55841bffe5d73be196..c78762051da4e5b15da45fa06b46b66d85e55d82 100644 (file)
@@ -772,12 +772,12 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
        separator[1] = 0; 
 
        memset(vol->source_rfc1001_name,0x20,15);
-       for(i=0;i < strnlen(system_utsname.nodename,15);i++) {
+       for(i=0;i < strnlen(utsname()->nodename,15);i++) {
                /* does not have to be a perfect mapping since the field is
                informational, only used for servers that do not support
                port 445 and it can be overridden at mount time */
                vol->source_rfc1001_name[i] = 
-                       toupper(system_utsname.nodename[i]);
+                       toupper(utsname()->nodename[i]);
        }
        vol->source_rfc1001_name[15] = 0;
        /* null target name indicates to use *SMBSERVR default called name
@@ -2153,7 +2153,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                  32, nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                bytes_returned =
-                   cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release,
+                   cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release,
                                  32, nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                bcc_ptr += 2;
@@ -2180,8 +2180,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                }
                strcpy(bcc_ptr, "Linux version ");
                bcc_ptr += strlen("Linux version ");
-               strcpy(bcc_ptr, system_utsname.release);
-               bcc_ptr += strlen(system_utsname.release) + 1;
+               strcpy(bcc_ptr, utsname()->release);
+               bcc_ptr += strlen(utsname()->release) + 1;
                strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
                bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
        }
@@ -2445,7 +2445,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
                                  32, nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                bytes_returned =
-                   cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
+                   cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
                                  nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                bcc_ptr += 2;   /* null terminate Linux version */
@@ -2462,8 +2462,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
        } else {                /* ASCII */
                strcpy(bcc_ptr, "Linux version ");
                bcc_ptr += strlen("Linux version ");
-               strcpy(bcc_ptr, system_utsname.release);
-               bcc_ptr += strlen(system_utsname.release) + 1;
+               strcpy(bcc_ptr, utsname()->release);
+               bcc_ptr += strlen(utsname()->release) + 1;
                strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
                bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
                bcc_ptr++;      /* empty domain field */
@@ -2836,7 +2836,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                  32, nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                bytes_returned =
-                   cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
+                   cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
                                  nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                bcc_ptr += 2;   /* null term version string */
@@ -2888,8 +2888,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
 
                strcpy(bcc_ptr, "Linux version ");
                bcc_ptr += strlen("Linux version ");
-               strcpy(bcc_ptr, system_utsname.release);
-               bcc_ptr += strlen(system_utsname.release) + 1;
+               strcpy(bcc_ptr, utsname()->release);
+               bcc_ptr += strlen(utsname()->release) + 1;
                strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
                bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
                bcc_ptr++;      /* null domain */
index d1705ab8136e1fc53768240d6dbca66bfcb56132..22b4c35dcfe3e4bfbc067b56880f5fb958df50ae 100644 (file)
@@ -111,7 +111,7 @@ static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
        bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32,
                                  nls_cp);
        bcc_ptr += 2 * bytes_ret;
-       bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release,
+       bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release,
                                  32, nls_cp);
        bcc_ptr += 2 * bytes_ret;
        bcc_ptr += 2; /* trailing null */
@@ -158,8 +158,8 @@ static void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
 
        strcpy(bcc_ptr, "Linux version ");
        bcc_ptr += strlen("Linux version ");
-       strcpy(bcc_ptr, system_utsname.release);
-       bcc_ptr += strlen(system_utsname.release) + 1;
+       strcpy(bcc_ptr, init_utsname()->release);
+       bcc_ptr += strlen(init_utsname()->release) + 1;
 
        strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
        bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
index 13fb08d096c436f5caba903abd57420935baa0cd..4d3fbcb2ddb1a32353dcf6001c9a4f53e42e94d4 100644 (file)
@@ -56,8 +56,6 @@
 
 int compat_log = 1;
 
-extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
-
 int compat_printk(const char *fmt, ...)
 {
        va_list ap;
@@ -916,20 +914,24 @@ struct compat_readdir_callback {
 };
 
 static int compat_fillonedir(void *__buf, const char *name, int namlen,
-                       loff_t offset, ino_t ino, unsigned int d_type)
+                       loff_t offset, u64 ino, unsigned int d_type)
 {
        struct compat_readdir_callback *buf = __buf;
        struct compat_old_linux_dirent __user *dirent;
+       compat_ulong_t d_ino;
 
        if (buf->result)
                return -EINVAL;
+       d_ino = ino;
+       if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+               return -EOVERFLOW;
        buf->result++;
        dirent = buf->dirent;
        if (!access_ok(VERIFY_WRITE, dirent,
                        (unsigned long)(dirent->d_name + namlen + 1) -
                                (unsigned long)dirent))
                goto efault;
-       if (    __put_user(ino, &dirent->d_ino) ||
+       if (    __put_user(d_ino, &dirent->d_ino) ||
                __put_user(offset, &dirent->d_offset) ||
                __put_user(namlen, &dirent->d_namlen) ||
                __copy_to_user(dirent->d_name, name, namlen) ||
@@ -980,22 +982,26 @@ struct compat_getdents_callback {
 };
 
 static int compat_filldir(void *__buf, const char *name, int namlen,
-               loff_t offset, ino_t ino, unsigned int d_type)
+               loff_t offset, u64 ino, unsigned int d_type)
 {
        struct compat_linux_dirent __user * dirent;
        struct compat_getdents_callback *buf = __buf;
+       compat_ulong_t d_ino;
        int reclen = COMPAT_ROUND_UP(NAME_OFFSET(dirent) + namlen + 2);
 
        buf->error = -EINVAL;   /* only used if we fail.. */
        if (reclen > buf->count)
                return -EINVAL;
+       d_ino = ino;
+       if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+               return -EOVERFLOW;
        dirent = buf->previous;
        if (dirent) {
                if (__put_user(offset, &dirent->d_off))
                        goto efault;
        }
        dirent = buf->current_dir;
-       if (__put_user(ino, &dirent->d_ino))
+       if (__put_user(d_ino, &dirent->d_ino))
                goto efault;
        if (__put_user(reclen, &dirent->d_reclen))
                goto efault;
@@ -1066,7 +1072,7 @@ struct compat_getdents_callback64 {
 };
 
 static int compat_filldir64(void * __buf, const char * name, int namlen, loff_t offset,
-                    ino_t ino, unsigned int d_type)
+                    u64 ino, unsigned int d_type)
 {
        struct linux_dirent64 __user *dirent;
        struct compat_getdents_callback64 *buf = __buf;
index 85105e50f7db668702b36ea78a32feaa6ef12593..e6d5754a715ecde980dd50225495d3628c49e2d8 100644 (file)
@@ -137,8 +137,8 @@ configfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *pp
                if ((retval = fill_read_buffer(file->f_dentry,buffer)))
                        goto out;
        }
-       pr_debug("%s: count = %d, ppos = %lld, buf = %s\n",
-                __FUNCTION__,count,*ppos,buffer->page);
+       pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n",
+                __FUNCTION__, count, *ppos, buffer->page);
        retval = flush_read_buffer(buffer,buf,count,ppos);
 out:
        up(&buffer->sem);
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
index f932591df5a43d00af7b2a6c72db3a1de1fdcb3b..2b0442db67e05cb7b0a275dafd0f7c762d86e050 100644 (file)
@@ -92,7 +92,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
                prev = &odn->dn_next;
        }
 
-       error = f_setown(filp, current->pid, 0);
+       error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0);
        if (error)
                goto out_free;
 
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 8d544334bcd22d216b057620900834e73b756698..557d5b614fae6ba694703b86d950471cc2eeedc5 100644 (file)
@@ -720,9 +720,10 @@ static int ep_getfd(int *efd, struct inode **einode, struct file **efile,
 
        /* Allocates an inode from the eventpoll file system */
        inode = ep_eventpoll_inode();
-       error = PTR_ERR(inode);
-       if (IS_ERR(inode))
+       if (IS_ERR(inode)) {
+               error = PTR_ERR(inode);
                goto eexit_2;
+       }
 
        /* Allocates a free descriptor to plug the file onto */
        error = get_unused_fd();
index 6270f8f20a638195b1e1c1fc59bba00d8f4d2bd3..d993ea1a81aee7b60cdc11ffc9ee18dd09a8658d 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1318,7 +1318,7 @@ static void format_corename(char *corename, const char *pattern, long signr)
                        case 'h':
                                down_read(&uts_sem);
                                rc = snprintf(out_ptr, out_end - out_ptr,
-                                             "%s", system_utsname.nodename);
+                                             "%s", utsname()->nodename);
                                up_read(&uts_sem);
                                if (rc > out_end - out_ptr)
                                        goto out;
index 4c39009350f3e59529363108800c003de2e2d2d0..93e77c3d24906af5156254b29ee1cd3e39ba1ac3 100644 (file)
@@ -315,7 +315,7 @@ struct getdents_callback {
  * the name matching the specified inode number.
  */
 static int filldir_one(void * __buf, const char * name, int len,
-                       loff_t pos, ino_t ino, unsigned int d_type)
+                       loff_t pos, u64 ino, unsigned int d_type)
 {
        struct getdents_callback *buf = __buf;
        int result = 0;
index 3e50a41662834834538886e5cd0aa4d48d0c3b08..69c439f443877be9bf72e28760d939581b5a00d5 100644 (file)
@@ -648,7 +648,7 @@ static int fat_readdir(struct file *filp, void *dirent, filldir_t filldir)
 }
 
 static int fat_ioctl_filldir(void *__buf, const char *name, int name_len,
-                            loff_t offset, ino_t ino, unsigned int d_type)
+                            loff_t offset, u64 ino, unsigned int d_type)
 {
        struct fat_ioctl_filldir_callback *buf = __buf;
        struct dirent __user *d1 = buf->dirent;
index d35cbc6bc11206b528a47672678d4337c933ecec..e4f26165f12a22567526a74d2f463aa6d6798547 100644 (file)
@@ -250,19 +250,22 @@ static int setfl(int fd, struct file * filp, unsigned long arg)
        return error;
 }
 
-static void f_modown(struct file *filp, unsigned long pid,
+static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
                      uid_t uid, uid_t euid, int force)
 {
        write_lock_irq(&filp->f_owner.lock);
        if (force || !filp->f_owner.pid) {
-               filp->f_owner.pid = pid;
+               put_pid(filp->f_owner.pid);
+               filp->f_owner.pid = get_pid(pid);
+               filp->f_owner.pid_type = type;
                filp->f_owner.uid = uid;
                filp->f_owner.euid = euid;
        }
        write_unlock_irq(&filp->f_owner.lock);
 }
 
-int f_setown(struct file *filp, unsigned long arg, int force)
+int __f_setown(struct file *filp, struct pid *pid, enum pid_type type,
+               int force)
 {
        int err;
        
@@ -270,15 +273,44 @@ int f_setown(struct file *filp, unsigned long arg, int force)
        if (err)
                return err;
 
-       f_modown(filp, arg, current->uid, current->euid, force);
+       f_modown(filp, pid, type, current->uid, current->euid, force);
        return 0;
 }
+EXPORT_SYMBOL(__f_setown);
 
+int f_setown(struct file *filp, unsigned long arg, int force)
+{
+       enum pid_type type;
+       struct pid *pid;
+       int who = arg;
+       int result;
+       type = PIDTYPE_PID;
+       if (who < 0) {
+               type = PIDTYPE_PGID;
+               who = -who;
+       }
+       rcu_read_lock();
+       pid = find_pid(who);
+       result = __f_setown(filp, pid, type, force);
+       rcu_read_unlock();
+       return result;
+}
 EXPORT_SYMBOL(f_setown);
 
 void f_delown(struct file *filp)
 {
-       f_modown(filp, 0, 0, 0, 1);
+       f_modown(filp, NULL, PIDTYPE_PID, 0, 0, 1);
+}
+
+pid_t f_getown(struct file *filp)
+{
+       pid_t pid;
+       read_lock(&filp->f_owner.lock);
+       pid = pid_nr(filp->f_owner.pid);
+       if (filp->f_owner.pid_type == PIDTYPE_PGID)
+               pid = -pid;
+       read_unlock(&filp->f_owner.lock);
+       return pid;
 }
 
 static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
@@ -319,7 +351,7 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
                 * current syscall conventions, the only way
                 * to fix this will be in libc.
                 */
-               err = filp->f_owner.pid;
+               err = f_getown(filp);
                force_successful_syscall_return();
                break;
        case F_SETOWN:
@@ -470,24 +502,19 @@ static void send_sigio_to_task(struct task_struct *p,
 void send_sigio(struct fown_struct *fown, int fd, int band)
 {
        struct task_struct *p;
-       int pid;
+       enum pid_type type;
+       struct pid *pid;
        
        read_lock(&fown->lock);
+       type = fown->pid_type;
        pid = fown->pid;
        if (!pid)
                goto out_unlock_fown;
        
        read_lock(&tasklist_lock);
-       if (pid > 0) {
-               p = find_task_by_pid(pid);
-               if (p) {
-                       send_sigio_to_task(p, fown, fd, band);
-               }
-       } else {
-               do_each_task_pid(-pid, PIDTYPE_PGID, p) {
-                       send_sigio_to_task(p, fown, fd, band);
-               } while_each_task_pid(-pid, PIDTYPE_PGID, p);
-       }
+       do_each_pid_task(pid, type, p) {
+               send_sigio_to_task(p, fown, fd, band);
+       } while_each_pid_task(pid, type, p);
        read_unlock(&tasklist_lock);
  out_unlock_fown:
        read_unlock(&fown->lock);
@@ -503,9 +530,12 @@ static void send_sigurg_to_task(struct task_struct *p,
 int send_sigurg(struct fown_struct *fown)
 {
        struct task_struct *p;
-       int pid, ret = 0;
+       enum pid_type type;
+       struct pid *pid;
+       int ret = 0;
        
        read_lock(&fown->lock);
+       type = fown->pid_type;
        pid = fown->pid;
        if (!pid)
                goto out_unlock_fown;
@@ -513,16 +543,9 @@ int send_sigurg(struct fown_struct *fown)
        ret = 1;
        
        read_lock(&tasklist_lock);
-       if (pid > 0) {
-               p = find_task_by_pid(pid);
-               if (p) {
-                       send_sigurg_to_task(p, fown);
-               }
-       } else {
-               do_each_task_pid(-pid, PIDTYPE_PGID, p) {
-                       send_sigurg_to_task(p, fown);
-               } while_each_task_pid(-pid, PIDTYPE_PGID, p);
-       }
+       do_each_pid_task(pid, type, p) {
+               send_sigurg_to_task(p, fown);
+       } while_each_pid_task(pid, type, p);
        read_unlock(&tasklist_lock);
  out_unlock_fown:
        read_unlock(&fown->lock);
index bc35a40417d7ada53223f5c93ed26875af97a646..24f25a057d9c131f94f1f2eb2400739958d09a95 100644 (file)
@@ -174,6 +174,7 @@ void fastcall __fput(struct file *file)
        fops_put(file->f_op);
        if (file->f_mode & FMODE_WRITE)
                put_write_access(inode);
+       put_pid(file->f_owner.pid);
        file_kill(file);
        file->f_dentry = NULL;
        file->f_vfsmnt = NULL;
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 ada7643104e14dee4bcc8a5dc5bd87b7398aad5f..bf6bec4e54ff648b4696c04909dcf2a5000c8748 100644 (file)
@@ -657,7 +657,7 @@ static struct inode * get_new_inode_fast(struct super_block *sb, struct hlist_he
        return inode;
 }
 
-static inline unsigned long hash(struct super_block *sb, unsigned long hashval)
+static unsigned long hash(struct super_block *sb, unsigned long hashval)
 {
        unsigned long tmp;
 
@@ -1003,7 +1003,7 @@ void generic_delete_inode(struct inode *inode)
 
        list_del_init(&inode->i_list);
        list_del_init(&inode->i_sb_list);
-       inode->i_state|=I_FREEING;
+       inode->i_state |= I_FREEING;
        inodes_stat.nr_inodes--;
        spin_unlock(&inode_lock);
 
@@ -1210,13 +1210,15 @@ void file_update_time(struct file *file)
                return;
 
        now = current_fs_time(inode->i_sb);
-       if (!timespec_equal(&inode->i_mtime, &now))
+       if (!timespec_equal(&inode->i_mtime, &now)) {
+               inode->i_mtime = now;
                sync_it = 1;
-       inode->i_mtime = now;
+       }
 
-       if (!timespec_equal(&inode->i_ctime, &now))
+       if (!timespec_equal(&inode->i_ctime, &now)) {
+               inode->i_ctime = now;
                sync_it = 1;
-       inode->i_ctime = now;
+       }
 
        if (sync_it)
                mark_inode_dirty_sync(inode);
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 e2281300979c7b2c5e09287e28364bb25733c648..4d84bdc882999150a1e9bd7ae829f1aff24b33f2 100644 (file)
@@ -5,16 +5,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -183,7 +183,7 @@ cleanup:
                posix_acl_release(acl);
        } else
                inode->i_mode &= ~current->fs->umask;
-       
+
        JFS_IP(inode)->mode2 = (JFS_IP(inode)->mode2 & 0xffff0000) |
                               inode->i_mode;
 
index ab7cd0567c958715e01b7f5ec7853a0c6e47ce7b..79494c4f2b10c2601c20044085d10815661d34a9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2001
+ *   Copyright (C) International Business Machines Corp., 2001
  *
  *   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
index 976e90dc2d1b52c33c82a3d5404b2043494ffb0d..34181b8f5a0ac6cbbbea4cee5fee75d5ab9e3175 100644 (file)
@@ -4,16 +4,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -108,7 +108,7 @@ const struct file_operations jfs_file_operations = {
        .aio_read       = generic_file_aio_read,
        .aio_write      = generic_file_aio_write,
        .mmap           = generic_file_mmap,
-       .sendfile       = generic_file_sendfile,
+       .sendfile       = generic_file_sendfile,
        .fsync          = jfs_fsync,
        .release        = jfs_release,
        .ioctl          = jfs_ioctl,
index a8cc169235d9b775f6aa7961d7b5d5dc011eea0d..f5719117edfe94e664e2dd46af752d7de8d9a142 100644 (file)
@@ -4,16 +4,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -33,7 +33,7 @@
 
 void jfs_read_inode(struct inode *inode)
 {
-       if (diRead(inode)) { 
+       if (diRead(inode)) {
                make_bad_inode(inode);
                return;
        }
index a76293767c73649048fb904698771b8d0da15845..455fa4292045559ea52202da59ae920dfe8d64ed 100644 (file)
@@ -1,18 +1,18 @@
 /*
- *   Copyright (c) International Business Machines  Corp., 2002
+ *   Copyright (C) International Business Machines  Corp., 2002
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef _H_JFS_ACL
index 7f3e9ac454fff1f34678e002740d65ecb9754415..79c61805bd3358baba69387cc511a943c85be502 100644 (file)
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef        _H_JFS_BTREE
index 81f0e514c4900c8fa679b429a3709ceb6decc318..9c5d59632aac98730aea6df4f5a50cac665e7a2c 100644 (file)
@@ -4,16 +4,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
index 9f2572aea5611b00279a771c760c6bbcf2126f7d..40b20111383c5f2c07419ab41cb5103fbed57a41 100644 (file)
@@ -1,18 +1,18 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2001
+ *   Copyright (C) International Business Machines Corp., 2000-2001
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef _H_JFS_DINODE
index f05ebb62918205a0a911e7668923acf0b6a9b054..23546c8fd48bd433c67f4233879c494f1c5457e9 100644 (file)
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
  *
  *     the working state of the block allocation map is accessed in
  *     two directions:
- *     
+ *
  *     1) allocation and free requests that start at the dmap
  *        level and move up through the dmap control pages (i.e.
  *        the vast majority of requests).
- * 
- *     2) allocation requests that start at dmap control page
+ *
+ *     2) allocation requests that start at dmap control page
  *        level and work down towards the dmaps.
- *     
- *     the serialization scheme used here is as follows. 
  *
- *     requests which start at the bottom are serialized against each 
- *     other through buffers and each requests holds onto its buffers 
- *     as it works it way up from a single dmap to the required level 
+ *     the serialization scheme used here is as follows.
+ *
+ *     requests which start at the bottom are serialized against each
+ *     other through buffers and each requests holds onto its buffers
+ *     as it works it way up from a single dmap to the required level
  *     of dmap control page.
  *     requests that start at the top are serialized against each other
  *     and request that start from the bottom by the multiple read/single
  *     write inode lock of the bmap inode. requests starting at the top
  *     take this lock in write mode while request starting at the bottom
  *     take the lock in read mode.  a single top-down request may proceed
- *     exclusively while multiple bottoms-up requests may proceed 
- *     simultaneously (under the protection of busy buffers).
- *     
+ *     exclusively while multiple bottoms-up requests may proceed
+ *     simultaneously (under the protection of busy buffers).
+ *
  *     in addition to information found in dmaps and dmap control pages,
  *     the working state of the block allocation map also includes read/
  *     write information maintained in the bmap descriptor (i.e. total
@@ -59,7 +59,7 @@
  *     a single exclusive lock (BMAP_LOCK) is used to guard this information
  *     in the face of multiple-bottoms up requests.
  *     (lock ordering: IREAD_LOCK, BMAP_LOCK);
- *     
+ *
  *     accesses to the persistent state of the block allocation map (limited
  *     to the persistent bitmaps in dmaps) is guarded by (busy) buffers.
  */
@@ -120,7 +120,7 @@ static int dbGetL2AGSize(s64 nblocks);
 /*
  *     buddy table
  *
- * table used for determining buddy sizes within characters of 
+ * table used for determining buddy sizes within characters of
  * dmap bitmap words.  the characters themselves serve as indexes
  * into the table, with the table elements yielding the maximum
  * binary buddy of free bits within the character.
@@ -146,7 +146,7 @@ static const s8 budtab[256] = {
 
 
 /*
- * NAME:       dbMount()
+ * NAME:       dbMount()
  *
  * FUNCTION:   initializate the block allocation map.
  *
@@ -223,12 +223,12 @@ int dbMount(struct inode *ipbmap)
 
 
 /*
- * NAME:       dbUnmount()
+ * NAME:       dbUnmount()
  *
  * FUNCTION:   terminate the block allocation map in preparation for
  *             file system unmount.
  *
- *             the in-core bmap descriptor is written to disk and
+ *             the in-core bmap descriptor is written to disk and
  *             the memory for this descriptor is freed.
  *
  * PARAMETERS:
@@ -311,7 +311,7 @@ int dbSync(struct inode *ipbmap)
 
 
 /*
- * NAME:       dbFree()
+ * NAME:       dbFree()
  *
  * FUNCTION:   free the specified block range from the working block
  *             allocation map.
@@ -397,7 +397,7 @@ int dbFree(struct inode *ip, s64 blkno, s64 nblocks)
  *
  * FUNCTION:    update the allocation state (free or allocate) of the
  *             specified block range in the persistent block allocation map.
- *             
+ *
  *             the blocks will be updated in the persistent map one
  *             dmap at a time.
  *
@@ -475,7 +475,7 @@ dbUpdatePMap(struct inode *ipbmap,
                /* update the bits of the dmap words. the first and last
                 * words may only have a subset of their bits updated. if
                 * this is the case, we'll work against that word (i.e.
-                * partial first and/or last) only in a single pass.  a 
+                * partial first and/or last) only in a single pass.  a
                 * single pass will also be used to update all words that
                 * are to have all their bits updated.
                 */
@@ -662,11 +662,11 @@ unlock:
  *             the block allocation policy uses hints and a multi-step
  *             approach.
  *
- *             for allocation requests smaller than the number of blocks
+ *             for allocation requests smaller than the number of blocks
  *             per dmap, we first try to allocate the new blocks
  *             immediately following the hint.  if these blocks are not
  *             available, we try to allocate blocks near the hint.  if
- *             no blocks near the hint are available, we next try to 
+ *             no blocks near the hint are available, we next try to
  *             allocate within the same dmap as contains the hint.
  *
  *             if no blocks are available in the dmap or the allocation
@@ -713,7 +713,7 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
 #endif                         /* _STILL_TO_PORT */
 
        /* get the log2 number of blocks to be allocated.
-        * if the number of blocks is not a log2 multiple, 
+        * if the number of blocks is not a log2 multiple,
         * it will be rounded up to the next log2 multiple.
         */
        l2nb = BLKSTOL2(nblocks);
@@ -906,7 +906,7 @@ int dbAllocExact(struct inode *ip, s64 blkno, int nblocks)
         * validate extent request:
         *
         * note: defragfs policy:
-        *  max 64 blocks will be moved.  
+        *  max 64 blocks will be moved.
         *  allocation request size must be satisfied from a single dmap.
         */
        if (nblocks <= 0 || nblocks > BPERDMAP || blkno >= bmp->db_mapsize) {
@@ -1333,7 +1333,7 @@ dbAllocNear(struct bmap * bmp,
  *             or two sub-trees, depending on the allocation group size.
  *             we search the top nodes of these subtrees left to right for
  *             sufficient free space.  if sufficient free space is found,
- *             the subtree is searched to find the leftmost leaf that 
+ *             the subtree is searched to find the leftmost leaf that
  *             has free space.  once we have made it to the leaf, we
  *             move the search to the next lower level dmap control page
  *             corresponding to this leaf.  we continue down the dmap control
@@ -1398,7 +1398,7 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
         * that fully describes the allocation group since the allocation
         * group is already fully described by a dmap.  in this case, we
         * just call dbAllocCtl() to search the dmap tree and allocate the
-        * required space if available.  
+        * required space if available.
         *
         * if the allocation group is completely free, dbAllocCtl() is
         * also called to allocate the required space.  this is done for
@@ -1450,7 +1450,7 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
            (1 << (L2LPERCTL - (bmp->db_agheigth << 1))) / bmp->db_agwidth;
        ti = bmp->db_agstart + bmp->db_agwidth * (agno & (agperlev - 1));
 
-       /* dmap control page trees fan-out by 4 and a single allocation 
+       /* dmap control page trees fan-out by 4 and a single allocation
         * group may be described by 1 or 2 subtrees within the ag level
         * dmap control page, depending upon the ag size. examine the ag's
         * subtrees for sufficient free space, starting with the leftmost
@@ -1633,7 +1633,7 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno)
 
        /* starting at the specified dmap control page level and block
         * number, search down the dmap control levels for the starting
-        * block number of a dmap page that contains or starts off 
+        * block number of a dmap page that contains or starts off
         * sufficient free blocks.
         */
        for (lev = level, b = *blkno; lev >= 0; lev--) {
@@ -1677,7 +1677,7 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno)
                }
 
                /* adjust the block number to reflect the location within
-                * the dmap control page (i.e. the leaf) at which free 
+                * the dmap control page (i.e. the leaf) at which free
                 * space was found.
                 */
                b += (((s64) leafidx) << budmin);
@@ -1700,12 +1700,12 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno)
  * NAME:       dbAllocCtl()
  *
  * FUNCTION:    attempt to allocate a specified number of contiguous
- *             blocks starting within a specific dmap.  
- *             
+ *             blocks starting within a specific dmap.
+ *
  *             this routine is called by higher level routines that search
  *             the dmap control pages above the actual dmaps for contiguous
  *             free space.  the result of successful searches by these
- *             routines are the starting block numbers within dmaps, with
+ *             routines are the starting block numbers within dmaps, with
  *             the dmaps themselves containing the desired contiguous free
  *             space or starting a contiguous free space of desired size
  *             that is made up of the blocks of one or more dmaps. these
@@ -1872,14 +1872,14 @@ dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, s64 * results)
  *
  * FUNCTION:    attempt to allocate a specified number of contiguous blocks
  *             from a specified dmap.
- *             
+ *
  *             this routine checks if the contiguous blocks are available.
  *             if so, nblocks of blocks are allocated; otherwise, ENOSPC is
  *             returned.
  *
  * PARAMETERS:
  *      mp     -  pointer to bmap descriptor
- *      dp     -  pointer to dmap to attempt to allocate blocks from. 
+ *      dp     -  pointer to dmap to attempt to allocate blocks from.
  *      l2nb   -  log2 number of contiguous block desired.
  *      nblocks        -  actual number of contiguous block desired.
  *      results        -  on successful return, set to the starting block number
@@ -1890,7 +1890,7 @@ dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, s64 * results)
  *      -ENOSPC        - insufficient disk resources
  *      -EIO   - i/o error
  *
- * serialization: IREAD_LOCK(ipbmap), e.g., from dbAlloc(), or 
+ * serialization: IREAD_LOCK(ipbmap), e.g., from dbAlloc(), or
  *     IWRITE_LOCK(ipbmap), e.g., dbAllocCtl(), held on entry/exit;
  */
 static int
@@ -2032,7 +2032,7 @@ static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
 
        /* root changed. bubble the change up to the dmap control pages.
         * if the adjustment of the upper level control pages fails,
-        * backout the deallocation. 
+        * backout the deallocation.
         */
        if ((rc = dbAdjCtl(bmp, blkno, dp->tree.stree[ROOT], 0, 0))) {
                word = (blkno & (BPERDMAP - 1)) >> L2DBWORD;
@@ -2245,7 +2245,7 @@ static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
         * words (i.e. partial first and/or last) on an individual basis
         * (a single pass), freeing the bits of interest by hand and updating
         * the leaf corresponding to the dmap word. a single pass will be used
-        * for all dmap words fully contained within the specified range.  
+        * for all dmap words fully contained within the specified range.
         * within this pass, the bits of all fully contained dmap words will
         * be marked as free in a single shot and the leaves will be updated. a
         * single leaf may describe the free space of multiple dmap words,
@@ -2267,7 +2267,7 @@ static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
                 */
                if (nb < DBWORD) {
                        /* free (zero) the appropriate bits within this
-                        * dmap word. 
+                        * dmap word.
                         */
                        dp->wmap[word] &=
                            cpu_to_le32(~(ONES << (DBWORD - nb)
@@ -2327,7 +2327,7 @@ static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
 
        BMAP_LOCK(bmp);
 
-       /* update the free count for the allocation group and 
+       /* update the free count for the allocation group and
         * map.
         */
        agno = blkno >> bmp->db_agl2size;
@@ -2378,7 +2378,7 @@ static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
  *             or deallocation resulted in the root change.  this range
  *             is respresented by a single leaf of the current dmapctl
  *             and the leaf will be updated with this value, possibly
- *             causing a binary buddy system within the leaves to be 
+ *             causing a binary buddy system within the leaves to be
  *             split or joined.  the update may also cause the dmapctl's
  *             dmtree to be updated.
  *
@@ -2590,7 +2590,7 @@ static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval)
                }
        }
 
-       /* adjust the dmap tree to reflect the specified leaf's new 
+       /* adjust the dmap tree to reflect the specified leaf's new
         * value.
         */
        dbAdjTree(tp, leafno, newval);
@@ -2638,7 +2638,7 @@ static int dbBackSplit(dmtree_t * tp, int leafno)
        /* the back split is accomplished by iteratively finding the leaf
         * that starts the buddy system that contains the specified leaf and
         * splitting that system in two.  this iteration continues until
-        * the specified leaf becomes the start of a buddy system. 
+        * the specified leaf becomes the start of a buddy system.
         *
         * determine maximum possible l2 size for the specified leaf.
         */
@@ -2853,7 +2853,7 @@ static void dbAdjTree(dmtree_t * tp, int leafno, int newval)
  * NAME:       dbFindLeaf()
  *
  * FUNCTION:    search a dmtree_t for sufficient free blocks, returning
- *             the index of a leaf describing the free blocks if 
+ *             the index of a leaf describing the free blocks if
  *             sufficient free blocks are found.
  *
  *             the search starts at the top of the dmtree_t tree and
@@ -2869,7 +2869,7 @@ static void dbAdjTree(dmtree_t * tp, int leafno, int newval)
  *
  * RETURN VALUES:
  *      0      - success
- *      -ENOSPC        - insufficient free blocks. 
+ *      -ENOSPC        - insufficient free blocks.
  */
 static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx)
 {
@@ -3090,7 +3090,7 @@ static int blkstol2(s64 nb)
 
 
 /*
- * NAME:       dbAllocBottomUp()
+ * NAME:       dbAllocBottomUp()
  *
  * FUNCTION:   alloc the specified block range from the working block
  *             allocation map.
@@ -3241,7 +3241,7 @@ static int dbAllocDmapBU(struct bmap * bmp, struct dmap * dp, s64 blkno,
        BMAP_LOCK(bmp);
 
        /* if this allocation group is completely free,
-        * update the highest active allocation group number 
+        * update the highest active allocation group number
         * if this allocation group is the new max.
         */
        agno = blkno >> bmp->db_agl2size;
@@ -3273,7 +3273,7 @@ static int dbAllocDmapBU(struct bmap * bmp, struct dmap * dp, s64 blkno,
  * NAME:       dbExtendFS()
  *
  * FUNCTION:   extend bmap from blkno for nblocks;
- *             dbExtendFS() updates bmap ready for dbAllocBottomUp();
+ *             dbExtendFS() updates bmap ready for dbAllocBottomUp();
  *
  * L2
  *  |
@@ -3284,7 +3284,7 @@ static int dbAllocDmapBU(struct bmap * bmp, struct dmap * dp, s64 blkno,
  *       d0,...,dn  d0,...,dn  d0,...,dn    d0,...,dn  d0,...,dn  d0,.,dm;
  * L2L1L0d0,...,dnL0d0,...,dnL0d0,...,dnL1L0d0,...,dnL0d0,...,dnL0d0,..dm
  *
- * <---old---><----------------------------extend----------------------->   
+ * <---old---><----------------------------extend----------------------->
  */
 int dbExtendFS(struct inode *ipbmap, s64 blkno,        s64 nblocks)
 {
@@ -3330,7 +3330,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno,   s64 nblocks)
        bmp->db_numag += ((u32) newsize % (u32) bmp->db_agsize) ? 1 : 0;
 
        /*
-        *      reconfigure db_agfree[] 
+        *      reconfigure db_agfree[]
         * from old AG configuration to new AG configuration;
         *
         * coalesce contiguous k (newAGSize/oldAGSize) AGs;
@@ -3491,7 +3491,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno,   s64 nblocks)
                        }       /* for each dmap in a L0 */
 
                        /*
-                        * build current L0 page from its leaves, and 
+                        * build current L0 page from its leaves, and
                         * initialize corresponding parent L1 leaf
                         */
                        *l1leaf = dbInitDmapCtl(l0dcp, 0, ++i);
@@ -3515,7 +3515,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno,   s64 nblocks)
                }               /* for each L0 in a L1 */
 
                /*
-                * build current L1 page from its leaves, and 
+                * build current L1 page from its leaves, and
                 * initialize corresponding parent L2 leaf
                 */
                *l2leaf = dbInitDmapCtl(l1dcp, 1, ++j);
@@ -3570,7 +3570,7 @@ void dbFinalizeBmap(struct inode *ipbmap)
         *      finalize bmap control page
         */
 //finalize:
-       /* 
+       /*
         * compute db_agpref: preferred ag to allocate from
         * (the leftmost ag with average free space in it);
         */
@@ -3614,9 +3614,9 @@ void dbFinalizeBmap(struct inode *ipbmap)
 
        /*
         * compute db_aglevel, db_agheigth, db_width, db_agstart:
-        * an ag is covered in aglevel dmapctl summary tree, 
-        * at agheight level height (from leaf) with agwidth number of nodes 
-        * each, which starts at agstart index node of the smmary tree node 
+        * an ag is covered in aglevel dmapctl summary tree,
+        * at agheight level height (from leaf) with agwidth number of nodes
+        * each, which starts at agstart index node of the smmary tree node
         * array;
         */
        bmp->db_aglevel = BMAPSZTOLEV(bmp->db_agsize);
@@ -3635,13 +3635,13 @@ void dbFinalizeBmap(struct inode *ipbmap)
 
 /*
  * NAME:       dbInitDmap()/ujfs_idmap_page()
- *                                                                    
+ *
  * FUNCTION:   initialize working/persistent bitmap of the dmap page
  *             for the specified number of blocks:
- *                                                                    
+ *
  *             at entry, the bitmaps had been initialized as free (ZEROS);
- *             The number of blocks will only account for the actually 
- *             existing blocks. Blocks which don't actually exist in 
+ *             The number of blocks will only account for the actually
+ *             existing blocks. Blocks which don't actually exist in
  *             the aggregate will be marked as allocated (ONES);
  *
  * PARAMETERS:
@@ -3677,7 +3677,7 @@ static int dbInitDmap(struct dmap * dp, s64 Blkno, int nblocks)
 
        /*
         * free the bits corresponding to the block range (ZEROS):
-        * note: not all bits of the first and last words may be contained 
+        * note: not all bits of the first and last words may be contained
         * within the block range.
         */
        for (r = nblocks; r > 0; r -= nb, blkno += nb) {
@@ -3709,7 +3709,7 @@ static int dbInitDmap(struct dmap * dp, s64 Blkno, int nblocks)
        }
 
        /*
-        * mark bits following the range to be freed (non-existing 
+        * mark bits following the range to be freed (non-existing
         * blocks) as allocated (ONES)
         */
 
@@ -3741,11 +3741,11 @@ static int dbInitDmap(struct dmap * dp, s64 Blkno, int nblocks)
 
 /*
  * NAME:       dbInitDmapTree()/ujfs_complete_dmap()
- *                                                                    
+ *
  * FUNCTION:   initialize summary tree of the specified dmap:
  *
  *             at entry, bitmap of the dmap has been initialized;
- *                                                                    
+ *
  * PARAMETERS:
  *     dp      - dmap to complete
  *     blkno   - starting block number for this dmap
@@ -3769,7 +3769,7 @@ static int dbInitDmapTree(struct dmap * dp)
 
        /* init each leaf from corresponding wmap word:
         * note: leaf is set to NOFREE(-1) if all blocks of corresponding
-        * bitmap word are allocated. 
+        * bitmap word are allocated.
         */
        cp = tp->stree + le32_to_cpu(tp->leafidx);
        for (i = 0; i < LPERDMAP; i++)
@@ -3782,10 +3782,10 @@ static int dbInitDmapTree(struct dmap * dp)
 
 /*
  * NAME:       dbInitTree()/ujfs_adjtree()
- *                                                                    
+ *
  * FUNCTION:   initialize binary buddy summary tree of a dmap or dmapctl.
  *
- *             at entry, the leaves of the tree has been initialized 
+ *             at entry, the leaves of the tree has been initialized
  *             from corresponding bitmap word or root of summary tree
  *             of the child control page;
  *             configure binary buddy system at the leaf level, then
@@ -3813,15 +3813,15 @@ static int dbInitTree(struct dmaptree * dtp)
        /*
         * configure the leaf levevl into binary buddy system
         *
-        * Try to combine buddies starting with a buddy size of 1 
-        * (i.e. two leaves). At a buddy size of 1 two buddy leaves 
-        * can be combined if both buddies have a maximum free of l2min; 
-        * the combination will result in the left-most buddy leaf having 
-        * a maximum free of l2min+1.  
-        * After processing all buddies for a given size, process buddies 
-        * at the next higher buddy size (i.e. current size * 2) and 
-        * the next maximum free (current free + 1).  
-        * This continues until the maximum possible buddy combination 
+        * Try to combine buddies starting with a buddy size of 1
+        * (i.e. two leaves). At a buddy size of 1 two buddy leaves
+        * can be combined if both buddies have a maximum free of l2min;
+        * the combination will result in the left-most buddy leaf having
+        * a maximum free of l2min+1.
+        * After processing all buddies for a given size, process buddies
+        * at the next higher buddy size (i.e. current size * 2) and
+        * the next maximum free (current free + 1).
+        * This continues until the maximum possible buddy combination
         * yields maximum free.
         */
        for (l2free = dtp->budmin, bsize = 1; l2free < l2max;
@@ -3845,10 +3845,10 @@ static int dbInitTree(struct dmaptree * dtp)
         * bubble summary information of leaves up the tree.
         *
         * Starting at the leaf node level, the four nodes described by
-        * the higher level parent node are compared for a maximum free and 
-        * this maximum becomes the value of the parent node.  
-        * when all lower level nodes are processed in this fashion then 
-        * move up to the next level (parent becomes a lower level node) and 
+        * the higher level parent node are compared for a maximum free and
+        * this maximum becomes the value of the parent node.
+        * when all lower level nodes are processed in this fashion then
+        * move up to the next level (parent becomes a lower level node) and
         * continue the process for that level.
         */
        for (child = le32_to_cpu(dtp->leafidx),
@@ -3857,7 +3857,7 @@ static int dbInitTree(struct dmaptree * dtp)
                /* get index of 1st node of parent level */
                parent = (child - 1) >> 2;
 
-               /* set the value of the parent node as the maximum 
+               /* set the value of the parent node as the maximum
                 * of the four nodes of the current level.
                 */
                for (i = 0, cp = tp + child, cp1 = tp + parent;
@@ -3885,8 +3885,8 @@ static int dbInitDmapCtl(struct dmapctl * dcp, int level, int i)
        dcp->budmin = L2BPERDMAP + L2LPERCTL * level;
 
        /*
-        * initialize the leaves of current level that were not covered 
-        * by the specified input block range (i.e. the leaves have no 
+        * initialize the leaves of current level that were not covered
+        * by the specified input block range (i.e. the leaves have no
         * low level dmapctl or dmap).
         */
        cp = &dcp->stree[CTLLEAFIND + i];
@@ -3900,9 +3900,9 @@ static int dbInitDmapCtl(struct dmapctl * dcp, int level, int i)
 
 /*
  * NAME:       dbGetL2AGSize()/ujfs_getagl2size()
- *                                                                    
+ *
  * FUNCTION:   Determine log2(allocation group size) from aggregate size
- *                                                                    
+ *
  * PARAMETERS:
  *     nblocks - Number of blocks in aggregate
  *
@@ -3935,8 +3935,8 @@ static int dbGetL2AGSize(s64 nblocks)
 
 /*
  * NAME:       dbMapFileSizeToMapSize()
- *                                                                    
- * FUNCTION:   compute number of blocks the block allocation map file 
+ *
+ * FUNCTION:   compute number of blocks the block allocation map file
  *             can cover from the map file size;
  *
  * RETURNS:    Number of blocks which can be covered by this block map file;
@@ -3968,7 +3968,7 @@ s64 dbMapFileSizeToMapSize(struct inode * ipbmap)
        npages = nblocks >> JFS_SBI(sb)->l2nbperpage;
        level = BMAPPGTOLEV(npages);
 
-       /* At each level, accumulate the number of dmap pages covered by 
+       /* At each level, accumulate the number of dmap pages covered by
         * the number of full child levels below it;
         * repeat for the last incomplete child level.
         */
@@ -3990,7 +3990,7 @@ s64 dbMapFileSizeToMapSize(struct inode * ipbmap)
                npages--;
        }
 
-       /* convert the number of dmaps into the number of blocks 
+       /* convert the number of dmaps into the number of blocks
         * which can be covered by the dmaps;
         */
        nblocks = ndmaps << L2BPERDMAP;
index 8b14cc8e0228346d703e6bb45509214d0b116be9..45ea454c74bd03f615fac463793ace154d9a7b1f 100644 (file)
@@ -1,18 +1,18 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2002
+ *   Copyright (C) International Business Machines Corp., 2000-2002
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef        _H_JFS_DMAP
@@ -27,7 +27,7 @@
 #define L2LPERDMAP     8       /* l2 number of leaves per dmap tree */
 #define        DBWORD          32      /* # of blks covered by a map word */
 #define        L2DBWORD        5       /* l2 # of blks covered by a mword */
-#define BUDMIN         L2DBWORD        /* max free string in a map word */
+#define BUDMIN         L2DBWORD        /* max free string in a map word */
 #define BPERDMAP       (LPERDMAP * DBWORD)     /* num of blks per dmap */
 #define L2BPERDMAP     13      /* l2 num of blks per dmap */
 #define CTLTREESIZE    (1024+256+64+16+4+1)    /* size of a dmapctl tree */
@@ -57,7 +57,7 @@
 
 #define        MAXMAPSIZE      MAXL2SIZE       /* maximum aggregate map size */
 
-/* 
+/*
  * determine the maximum free string for four (lower level) nodes
  * of the tree.
  */
@@ -122,7 +122,7 @@ static __inline signed char TREEMAX(signed char *cp)
 #define BLKTOCTL(b,s,l)   \
         (((l) == 2) ? 1 : ((l) == 1) ? BLKTOL1((b),(s)) : BLKTOL0((b),(s)))
 
-/* 
+/*
  * convert aggregate map size to the zero origin dmapctl level of the
  * top dmapctl.
  */
@@ -192,13 +192,13 @@ typedef union dmtree {
 
 /* macros for accessing fields within dmtree */
 #define        dmt_nleafs      t1.nleafs
-#define        dmt_l2nleafs    t1.l2nleafs
-#define        dmt_leafidx     t1.leafidx
-#define        dmt_height      t1.height
-#define        dmt_budmin      t1.budmin
-#define        dmt_stree       t1.stree
+#define        dmt_l2nleafs    t1.l2nleafs
+#define        dmt_leafidx     t1.leafidx
+#define        dmt_height      t1.height
+#define        dmt_budmin      t1.budmin
+#define        dmt_stree       t1.stree
 
-/* 
+/*
  *     on-disk aggregate disk allocation map descriptor.
  */
 struct dbmap_disk {
@@ -237,7 +237,7 @@ struct dbmap {
        s64 dn_agsize;          /* num of blks per alloc group       */
        signed char dn_maxfreebud;      /* max free buddy system             */
 };                             /* - 4096 -                             */
-/* 
+/*
  *     in-memory aggregate disk allocation map descriptor.
  */
 struct bmap {
index 6c3f083198468a686af3ed7c4dcc6bcbaf782dd8..ecb2216d881ccf5fb76bbd46151cc14763866018 100644 (file)
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -78,7 +78,7 @@
  *
  * case-insensitive search:
  *
- *     fold search key;
+ *     fold search key;
  *
  *     case-insensitive search of B-tree:
  *     for internal entry, router key is already folded;
@@ -93,7 +93,7 @@
  *     else
  *             return no match;
  *
- *     serialization:
+ *     serialization:
  * target directory inode lock is being held on entry/exit
  * of all main directory service routines.
  *
@@ -925,7 +925,7 @@ int dtInsert(tid_t tid, struct inode *ip,
  *
  * return: 0 - success;
  *        errno - failure;
- *     leaf page unpinned;
+ *     leaf page unpinned;
  */
 static int dtSplitUp(tid_t tid,
          struct inode *ip, struct dtsplit * split, struct btstack * btstack)
@@ -3767,7 +3767,7 @@ static int ciCompare(struct component_name * key, /* search key */
  *          across page boundary
  *
  * return: non-zero on error
- *     
+ *
  */
 static int ciGetLeafPrefixKey(dtpage_t * lp, int li, dtpage_t * rp,
                               int ri, struct component_name * key, int flag)
@@ -3780,13 +3780,13 @@ static int ciGetLeafPrefixKey(dtpage_t * lp, int li, dtpage_t * rp,
        lkey.name = (wchar_t *) kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t),
                                        GFP_KERNEL);
        if (lkey.name == NULL)
-               return -ENOSPC;
+               return -ENOMEM;
 
        rkey.name = (wchar_t *) kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t),
                                        GFP_KERNEL);
        if (rkey.name == NULL) {
                kfree(lkey.name);
-               return -ENOSPC;
+               return -ENOMEM;
        }
 
        /* get left and right key */
index 13e4fdf07724daefbc6a659f0f682dcd0d4fdde5..af8513f78648336f8bda39c8e5c271b943a43535 100644 (file)
@@ -1,18 +1,18 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2002
+ *   Copyright (C) International Business Machines Corp., 2000-2002
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef _H_JFS_DTREE
@@ -80,7 +80,7 @@ struct idtentry {
 /*
  *     leaf node entry head/only segment
  *
- *     For legacy filesystems, name contains 13 wchars -- no index field
+ *     For legacy filesystems, name contains 13 wchars -- no index field
  */
 struct ldtentry {
        __le32 inumber;         /* 4: 4-byte aligned */
index 933b7457bfbd962334fd91209c0cd5d34243996c..a35bdca6a805b81b2fe2bf4b379a27d55c02dd5f 100644 (file)
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -125,7 +125,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr)
        }
 
        /* allocate the disk blocks for the extent.  initially, extBalloc()
-        * will try to allocate disk blocks for the requested size (xlen). 
+        * will try to allocate disk blocks for the requested size (xlen).
         * if this fails (xlen contiguous free blocks not avaliable), it'll
         * try to allocate a smaller number of blocks (producing a smaller
         * extent), with this smaller number of blocks consisting of the
@@ -150,7 +150,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr)
        /* determine the value of the extent flag */
        xflag = abnr ? XAD_NOTRECORDED : 0;
 
-       /* if we can extend the hint extent to cover the current request, 
+       /* if we can extend the hint extent to cover the current request,
         * extend it.  otherwise, insert a new extent to
         * cover the current request.
         */
@@ -159,7 +159,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr)
        else
                rc = xtInsert(0, ip, xflag, xoff, (int) nxlen, &nxaddr, 0);
 
-       /* if the extend or insert failed, 
+       /* if the extend or insert failed,
         * free the newly allocated blocks and return the error.
         */
        if (rc) {
@@ -235,7 +235,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, bool abnr)
        xoff = offsetXAD(xp);
 
        /* if the extend page is abnr and if the request is for
-        * the extent to be allocated and recorded, 
+        * the extent to be allocated and recorded,
         * make the page allocated and recorded.
         */
        if ((xp->flag & XAD_NOTRECORDED) && !abnr) {
@@ -397,7 +397,7 @@ int extHint(struct inode *ip, s64 offset, xad_t * xp)
        if ((rc = xtLookupList(ip, &lxdl, &xadl, 0)))
                return (rc);
 
-       /* check if not extent exists for the previous page.  
+       /* check if not extent exists for the previous page.
         * this is possible for sparse files.
         */
        if (xadl.nxad == 0) {
@@ -410,7 +410,7 @@ int extHint(struct inode *ip, s64 offset, xad_t * xp)
         */
        xp->flag &= XAD_NOTRECORDED;
 
-        if(xadl.nxad != 1 || lengthXAD(xp) != nbperpage) {          
+        if(xadl.nxad != 1 || lengthXAD(xp) != nbperpage) {
                jfs_error(ip->i_sb, "extHint: corrupt xtree");
                return -EIO;
         }
@@ -492,7 +492,7 @@ int extFill(struct inode *ip, xad_t * xp)
  * FUNCTION:    allocate disk blocks to form an extent.
  *
  *             initially, we will try to allocate disk blocks for the
- *             requested size (nblocks).  if this fails (nblocks 
+ *             requested size (nblocks).  if this fails (nblocks
  *             contiguous free blocks not avaliable), we'll try to allocate
  *             a smaller number of blocks (producing a smaller extent), with
  *             this smaller number of blocks consisting of the requested
@@ -500,7 +500,7 @@ int extFill(struct inode *ip, xad_t * xp)
  *             number (i.e. 16 -> 8).  we'll continue to round down and
  *             retry the allocation until the number of blocks to allocate
  *             is smaller than the number of blocks per page.
- *             
+ *
  * PARAMETERS:
  *     ip       - the inode of the file.
  *     hint     - disk block number to be used as an allocation hint.
@@ -509,7 +509,7 @@ int extFill(struct inode *ip, xad_t * xp)
  *                exit, this value is set to the number of blocks actually
  *                allocated.
  *     blkno    - pointer to a block address that is filled in on successful
- *                return with the starting block number of the newly 
+ *                return with the starting block number of the newly
  *                allocated block range.
  *
  * RETURN VALUES:
@@ -530,7 +530,7 @@ extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno)
        /* get the number of blocks to initially attempt to allocate.
         * we'll first try the number of blocks requested unless this
         * number is greater than the maximum number of contiguous free
-        * blocks in the map. in that case, we'll start off with the 
+        * blocks in the map. in that case, we'll start off with the
         * maximum free.
         */
        max = (s64) 1 << bmp->db_maxfreebud;
@@ -582,19 +582,19 @@ extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno)
  *
  * FUNCTION:    attempt to extend an extent's allocation.
  *
- *             initially, we will try to extend the extent's allocation
- *             in place.  if this fails, we'll try to move the extent
- *             to a new set of blocks. if moving the extent, we initially
+ *             Initially, we will try to extend the extent's allocation
+ *             in place.  If this fails, we'll try to move the extent
+ *             to a new set of blocks.  If moving the extent, we initially
  *             will try to allocate disk blocks for the requested size
- *             (nnew).  if this fails  (new contiguous free blocks not
- *             avaliable), we'll try  to allocate a smaller number of
+ *             (newnblks).  if this fails (new contiguous free blocks not
+ *             avaliable), we'll try to allocate a smaller number of
  *             blocks (producing a smaller extent), with this smaller
  *             number of blocks consisting of the requested number of
  *             blocks rounded down to the next smaller power of 2
- *             number (i.e. 16 -> 8).  we'll continue to round down and
+ *             number (i.e. 16 -> 8).  We'll continue to round down and
  *             retry the allocation until the number of blocks to allocate
  *             is smaller than the number of blocks per page.
- *             
+ *
  * PARAMETERS:
  *     ip       - the inode of the file.
  *     blkno    - starting block number of the extents current allocation.
@@ -625,7 +625,7 @@ extBrealloc(struct inode *ip,
                        return (rc);
        }
 
-       /* in place extension not possible.  
+       /* in place extension not possible.
         * try to move the extent to a new set of blocks.
         */
        return (extBalloc(ip, blkno, newnblks, newblkno));
index 3a7f3f22e989625c19e18ad693383ef18185b46c..b567e12c52d30af3d4fe9c2eb83723468cca2698 100644 (file)
@@ -1,18 +1,18 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2001
+ *   Copyright (C) International Business Machines Corp., 2000-2001
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef        _H_JFS_EXTENT
index 72a5588faecac5040a241448796d0cfb1e7a5b3f..9901928668cfe62395da77cceba9626dcac9249b 100644 (file)
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef _H_JFS_FILSYS
@@ -21,9 +21,9 @@
 /*
  *     jfs_filsys.h
  *
- * file system (implementation-dependent) constants 
+ * file system (implementation-dependent) constants
  *
- * refer to <limits.h> for system wide implementation-dependent constants 
+ * refer to <limits.h> for system wide implementation-dependent constants
  */
 
 /*
@@ -49,7 +49,7 @@
 
 #define JFS_DFS                0x20000000      /* DCE DFS LFS support */
 
-#define JFS_LINUX              0x10000000      /* Linux support */
+#define JFS_LINUX      0x10000000      /* Linux support */
 /*     case-sensitive name/directory support */
 
 /* directory option */
@@ -59,7 +59,7 @@
 #define        JFS_COMMIT      0x00000f00      /* commit option mask */
 #define        JFS_GROUPCOMMIT 0x00000100      /* group (of 1) commit */
 #define        JFS_LAZYCOMMIT  0x00000200      /* lazy commit */
-#define        JFS_TMPFS       0x00000400      /* temporary file system - 
+#define        JFS_TMPFS       0x00000400      /* temporary file system -
                                         * do not log/commit:
                                         */
 
                                         * followed by 1st extent of map
                                         */
 #define AITBL_OFF      (AIMAP_OFF + (SIZE_OF_MAP_PAGE << 1))
-                                       /* 
+                                       /*
                                         * 1st extent of aggregate inode table
                                         */
 #define SUPER2_OFF     (AITBL_OFF + INODE_EXTENT_SIZE)
  */
 #define FM_CLEAN 0x00000000    /* file system is unmounted and clean */
 #define FM_MOUNT 0x00000001    /* file system is mounted cleanly */
-#define FM_DIRTY 0x00000002    /* file system was not unmounted and clean 
-                                * when mounted or 
+#define FM_DIRTY 0x00000002    /* file system was not unmounted and clean
+                                * when mounted or
                                 * commit failure occurred while being mounted:
-                                * fsck() must be run to repair 
+                                * fsck() must be run to repair
                                 */
 #define        FM_LOGREDO 0x00000004   /* log based recovery (logredo()) failed:
-                                * fsck() must be run to repair 
+                                * fsck() must be run to repair
                                 */
 #define        FM_EXTENDFS 0x00000008  /* file system extendfs() in progress */
 
index a45ee2489580e234e2bf72bf2a74bdec681ec4f9..489a3d63002db2db9d5dec4a3c3f1899a154a4e7 100644 (file)
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -98,7 +98,7 @@ static void copy_to_dinode(struct dinode *, struct inode *);
  * FUNCTION:    initialize the incore inode map control structures for
  *             a fileset or aggregate init time.
  *
- *              the inode map's control structure (dinomap) is 
+ *              the inode map's control structure (dinomap) is
  *              brought in from disk and placed in virtual memory.
  *
  * PARAMETERS:
@@ -107,7 +107,7 @@ static void copy_to_dinode(struct dinode *, struct inode *);
  * RETURN VALUES:
  *      0       - success
  *      -ENOMEM  - insufficient free virtual memory.
- *      -EIO   - i/o error.
+ *      -EIO   - i/o error.
  */
 int diMount(struct inode *ipimap)
 {
@@ -191,7 +191,7 @@ int diMount(struct inode *ipimap)
  * RETURN VALUES:
  *      0       - success
  *      -ENOMEM  - insufficient free virtual memory.
- *      -EIO   - i/o error.
+ *      -EIO   - i/o error.
  */
 int diUnmount(struct inode *ipimap, int mounterror)
 {
@@ -281,7 +281,7 @@ int diSync(struct inode *ipimap)
  *             on entry, the specifed incore inode should itself
  *             specify the disk inode number corresponding to the
  *             incore inode (i.e. i_number should be initialized).
- *             
+ *
  *             this routine handles incore inode initialization for
  *             both "special" and "regular" inodes.  special inodes
  *             are those required early in the mount process and
@@ -289,7 +289,7 @@ int diSync(struct inode *ipimap)
  *             is not yet initialized.  these "special" inodes are
  *             identified by a NULL inode map inode pointer and are
  *             actually initialized by a call to diReadSpecial().
- *             
+ *
  *             for regular inodes, the iag describing the disk inode
  *             is read from disk to determine the inode extent address
  *             for the disk inode.  with the inode extent address in
@@ -302,9 +302,9 @@ int diSync(struct inode *ipimap)
  *
  * RETURN VALUES:
  *      0       - success
- *      -EIO   - i/o error.
+ *      -EIO   - i/o error.
  *      -ENOMEM        - insufficient memory
- *      
+ *
  */
 int diRead(struct inode *ip)
 {
@@ -586,14 +586,14 @@ void diFreeSpecial(struct inode *ip)
  *             page of the extent that contains the disk inode is
  *             read and the disk inode portion of the incore inode
  *             is copied to the disk inode.
- *             
+ *
  * PARAMETERS:
  *     tid -  transacation id
  *      ip  -  pointer to incore inode to be written to the inode extent.
  *
  * RETURN VALUES:
  *      0       - success
- *      -EIO   - i/o error.
+ *      -EIO   - i/o error.
  */
 int diWrite(tid_t tid, struct inode *ip)
 {
@@ -676,11 +676,11 @@ int diWrite(tid_t tid, struct inode *ip)
         * copy btree root from in-memory inode to on-disk inode
         *
         * (tlock is taken from inline B+-tree root in in-memory
-        * inode when the B+-tree root is updated, which is pointed 
+        * inode when the B+-tree root is updated, which is pointed
         * by jfs_ip->blid as well as being on tx tlock list)
         *
-        * further processing of btree root is based on the copy 
-        * in in-memory inode, where txLog() will log from, and, 
+        * further processing of btree root is based on the copy
+        * in in-memory inode, where txLog() will log from, and,
         * for xtree root, txUpdateMap() will update map and reset
         * XAD_NEW bit;
         */
@@ -824,7 +824,7 @@ int diWrite(tid_t tid, struct inode *ip)
                memcpy(&dp->di_DASD, &ip->i_DASD, sizeof(struct dasd));
 #endif                         /*  _JFS_FASTDASD */
 
-       /* release the buffer holding the updated on-disk inode. 
+       /* release the buffer holding the updated on-disk inode.
         * the buffer will be later written by commit processing.
         */
        write_metapage(mp);
@@ -842,7 +842,7 @@ int diWrite(tid_t tid, struct inode *ip)
  *             if the inode to be freed represents the first (only)
  *             free inode within the iag, the iag will be placed on
  *             the ag free inode list.
- *     
+ *
  *             freeing the inode will cause the inode extent to be
  *             freed if the inode is the only allocated inode within
  *             the extent.  in this case all the disk resource backing
@@ -865,11 +865,11 @@ int diWrite(tid_t tid, struct inode *ip)
  *             any updates and are held until all updates are complete.
  *
  * PARAMETERS:
- *      ip     - inode to be freed.
+ *      ip     - inode to be freed.
  *
  * RETURN VALUES:
  *      0       - success
- *      -EIO   - i/o error.
+ *      -EIO   - i/o error.
  */
 int diFree(struct inode *ip)
 {
@@ -898,7 +898,7 @@ int diFree(struct inode *ip)
         */
        iagno = INOTOIAG(inum);
 
-       /* make sure that the iag is contained within 
+       /* make sure that the iag is contained within
         * the map.
         */
        if (iagno >= imap->im_nextiag) {
@@ -1013,7 +1013,7 @@ int diFree(struct inode *ip)
 
                /* update the free inode summary map for the extent if
                 * freeing the inode means the extent will now have free
-                * inodes (i.e., the inode being freed is the first free 
+                * inodes (i.e., the inode being freed is the first free
                 * inode of extent),
                 */
                if (iagp->wmap[extno] == cpu_to_le32(ONES)) {
@@ -1204,9 +1204,9 @@ int diFree(struct inode *ip)
                iagp->inofreefwd = iagp->inofreeback = cpu_to_le32(-1);
        }
 
-       /* update the inode extent address and working map 
+       /* update the inode extent address and working map
         * to reflect the free extent.
-        * the permanent map should have been updated already 
+        * the permanent map should have been updated already
         * for the inode being freed.
         */
        if (iagp->pmap[extno] != 0) {
@@ -1218,7 +1218,7 @@ int diFree(struct inode *ip)
 
        /* update the free extent and free inode summary maps
         * to reflect the freed extent.
-        * the inode summary map is marked to indicate no inodes 
+        * the inode summary map is marked to indicate no inodes
         * available for the freed extent.
         */
        sword = extno >> L2EXTSPERSUM;
@@ -1255,17 +1255,17 @@ int diFree(struct inode *ip)
         * start transaction to update block allocation map
         * for the inode extent freed;
         *
-        * N.B. AG_LOCK is released and iag will be released below, and 
+        * N.B. AG_LOCK is released and iag will be released below, and
         * other thread may allocate inode from/reusing the ixad freed
-        * BUT with new/different backing inode extent from the extent 
-        * to be freed by the transaction;  
+        * BUT with new/different backing inode extent from the extent
+        * to be freed by the transaction;
         */
        tid = txBegin(ipimap->i_sb, COMMIT_FORCE);
        mutex_lock(&JFS_IP(ipimap)->commit_mutex);
 
-       /* acquire tlock of the iag page of the freed ixad 
+       /* acquire tlock of the iag page of the freed ixad
         * to force the page NOHOMEOK (even though no data is
-        * logged from the iag page) until NOREDOPAGE|FREEXTENT log 
+        * logged from the iag page) until NOREDOPAGE|FREEXTENT log
         * for the free of the extent is committed;
         * write FREEXTENT|NOREDOPAGE log record
         * N.B. linelock is overlaid as freed extent descriptor;
@@ -1284,8 +1284,8 @@ int diFree(struct inode *ip)
         * logredo needs the IAG number and IAG extent index in order
         * to ensure that the IMap is consistent.  The least disruptive
         * way to pass these values through  to the transaction manager
-        * is in the iplist array.  
-        * 
+        * is in the iplist array.
+        *
         * It's not pretty, but it works.
         */
        iplist[1] = (struct inode *) (size_t)iagno;
@@ -1340,18 +1340,18 @@ diInitInode(struct inode *ip, int iagno, int ino, int extno, struct iag * iagp)
 /*
  * NAME:        diAlloc(pip,dir,ip)
  *
- * FUNCTION:    allocate a disk inode from the inode working map 
+ * FUNCTION:    allocate a disk inode from the inode working map
  *             for a fileset or aggregate.
  *
  * PARAMETERS:
- *      pip    - pointer to incore inode for the parent inode.
- *      dir    - 'true' if the new disk inode is for a directory.
- *      ip     - pointer to a new inode
+ *      pip    - pointer to incore inode for the parent inode.
+ *      dir    - 'true' if the new disk inode is for a directory.
+ *      ip     - pointer to a new inode
  *
  * RETURN VALUES:
  *      0       - success.
  *      -ENOSPC        - insufficient disk resources.
- *      -EIO   - i/o error.
+ *      -EIO   - i/o error.
  */
 int diAlloc(struct inode *pip, bool dir, struct inode *ip)
 {
@@ -1372,7 +1372,7 @@ int diAlloc(struct inode *pip, bool dir, struct inode *ip)
        JFS_IP(ip)->ipimap = ipimap;
        JFS_IP(ip)->fileset = FILESYSTEM_I;
 
-       /* for a directory, the allocation policy is to start 
+       /* for a directory, the allocation policy is to start
         * at the ag level using the preferred ag.
         */
        if (dir) {
@@ -1435,7 +1435,7 @@ int diAlloc(struct inode *pip, bool dir, struct inode *ip)
        /*
         *      try to allocate from the IAG
         */
-       /* check if the inode may be allocated from the iag 
+       /* check if the inode may be allocated from the iag
         * (i.e. the inode has free inodes or new extent can be added).
         */
        if (iagp->nfreeinos || addext) {
@@ -1490,7 +1490,7 @@ int diAlloc(struct inode *pip, bool dir, struct inode *ip)
                 * hint or, if appropriate (i.e. addext is true), allocate
                 * an extent of free inodes at or following the extent
                 * containing the hint.
-                * 
+                *
                 * the free inode and free extent summary maps are used
                 * here, so determine the starting summary map position
                 * and the number of words we'll have to examine.  again,
@@ -1641,7 +1641,7 @@ int diAlloc(struct inode *pip, bool dir, struct inode *ip)
  *             inodes should be added for the allocation group, with
  *             the current request satisfied from this extent. if this
  *             is the case, an attempt will be made to do just that.  if
- *             this attempt fails or it has been determined that a new 
+ *             this attempt fails or it has been determined that a new
  *             extent should not be added, an attempt is made to satisfy
  *             the request by allocating an existing (backed) free inode
  *             from the allocation group.
@@ -1649,24 +1649,24 @@ int diAlloc(struct inode *pip, bool dir, struct inode *ip)
  * PRE CONDITION: Already have the AG lock for this AG.
  *
  * PARAMETERS:
- *      imap   - pointer to inode map control structure.
- *      agno   - allocation group to allocate from.
- *      dir    - 'true' if the new disk inode is for a directory.
- *      ip     - pointer to the new inode to be filled in on successful return
+ *      imap   - pointer to inode map control structure.
+ *      agno   - allocation group to allocate from.
+ *      dir    - 'true' if the new disk inode is for a directory.
+ *      ip     - pointer to the new inode to be filled in on successful return
  *               with the disk inode number allocated, its extent address
  *               and the start of the ag.
  *
  * RETURN VALUES:
  *      0       - success.
  *      -ENOSPC        - insufficient disk resources.
- *      -EIO   - i/o error.
+ *      -EIO   - i/o error.
  */
 static int
 diAllocAG(struct inomap * imap, int agno, bool dir, struct inode *ip)
 {
        int rc, addext, numfree, numinos;
 
-       /* get the number of free and the number of backed disk 
+       /* get the number of free and the number of backed disk
         * inodes currently within the ag.
         */
        numfree = imap->im_agctl[agno].numfree;
@@ -1719,17 +1719,17 @@ diAllocAG(struct inomap * imap, int agno, bool dir, struct inode *ip)
  *             specified primary group.
  *
  * PARAMETERS:
- *      imap   - pointer to inode map control structure.
- *      agno   - primary allocation group (to avoid).
- *      dir    - 'true' if the new disk inode is for a directory.
- *      ip     - pointer to a new inode to be filled in on successful return
+ *      imap   - pointer to inode map control structure.
+ *      agno   - primary allocation group (to avoid).
+ *      dir    - 'true' if the new disk inode is for a directory.
+ *      ip     - pointer to a new inode to be filled in on successful return
  *               with the disk inode number allocated, its extent address
  *               and the start of the ag.
  *
  * RETURN VALUES:
  *      0       - success.
  *      -ENOSPC        - insufficient disk resources.
- *      -EIO   - i/o error.
+ *      -EIO   - i/o error.
  */
 static int
 diAllocAny(struct inomap * imap, int agno, bool dir, struct inode *ip)
@@ -1738,7 +1738,7 @@ diAllocAny(struct inomap * imap, int agno, bool dir, struct inode *ip)
        int maxag = JFS_SBI(imap->im_ipimap->i_sb)->bmap->db_maxag;
 
 
-       /* try to allocate from the ags following agno up to 
+       /* try to allocate from the ags following agno up to
         * the maximum ag number.
         */
        for (ag = agno + 1; ag <= maxag; ag++) {
@@ -1780,21 +1780,21 @@ diAllocAny(struct inomap * imap, int agno, bool dir, struct inode *ip)
  *
  *             allocation occurs from the first iag on the list using
  *             the iag's free inode summary map to find the leftmost
- *             free inode in the iag. 
- *             
+ *             free inode in the iag.
+ *
  * PRE CONDITION: Already have AG lock for this AG.
- *             
+ *
  * PARAMETERS:
- *      imap   - pointer to inode map control structure.
- *      agno   - allocation group.
- *      ip     - pointer to new inode to be filled in on successful return
+ *      imap   - pointer to inode map control structure.
+ *      agno   - allocation group.
+ *      ip     - pointer to new inode to be filled in on successful return
  *               with the disk inode number allocated, its extent address
  *               and the start of the ag.
  *
  * RETURN VALUES:
  *      0       - success.
  *      -ENOSPC        - insufficient disk resources.
- *      -EIO   - i/o error.
+ *      -EIO   - i/o error.
  */
 static int diAllocIno(struct inomap * imap, int agno, struct inode *ip)
 {
@@ -1867,7 +1867,7 @@ static int diAllocIno(struct inomap * imap, int agno, struct inode *ip)
                return -EIO;
        }
 
-       /* compute the inode number within the iag. 
+       /* compute the inode number within the iag.
         */
        ino = (extno << L2INOSPEREXT) + rem;
 
@@ -1892,17 +1892,17 @@ static int diAllocIno(struct inomap * imap, int agno, struct inode *ip)
 /*
  * NAME:        diAllocExt(imap,agno,ip)
  *
- * FUNCTION:           add a new extent of free inodes to an iag, allocating
- *             an inode from this extent to satisfy the current allocation
- *             request.
- *             
+ * FUNCTION:   add a new extent of free inodes to an iag, allocating
+ *             an inode from this extent to satisfy the current allocation
+ *             request.
+ *
  *             this routine first tries to find an existing iag with free
  *             extents through the ag free extent list.  if list is not
  *             empty, the head of the list will be selected as the home
  *             of the new extent of free inodes.  otherwise (the list is
  *             empty), a new iag will be allocated for the ag to contain
  *             the extent.
- *             
+ *
  *             once an iag has been selected, the free extent summary map
  *             is used to locate a free extent within the iag and diNewExt()
  *             is called to initialize the extent, with initialization
@@ -1910,16 +1910,16 @@ static int diAllocIno(struct inomap * imap, int agno, struct inode *ip)
  *             for the purpose of satisfying this request.
  *
  * PARAMETERS:
- *      imap   - pointer to inode map control structure.
- *      agno   - allocation group number.
- *      ip     - pointer to new inode to be filled in on successful return
+ *      imap   - pointer to inode map control structure.
+ *      agno   - allocation group number.
+ *      ip     - pointer to new inode to be filled in on successful return
  *               with the disk inode number allocated, its extent address
  *               and the start of the ag.
  *
  * RETURN VALUES:
  *      0       - success.
  *      -ENOSPC        - insufficient disk resources.
- *      -EIO   - i/o error.
+ *      -EIO   - i/o error.
  */
 static int diAllocExt(struct inomap * imap, int agno, struct inode *ip)
 {
@@ -2012,7 +2012,7 @@ static int diAllocExt(struct inomap * imap, int agno, struct inode *ip)
 /*
  * NAME:        diAllocBit(imap,iagp,ino)
  *
- * FUNCTION:           allocate a backed inode from an iag.
+ * FUNCTION:   allocate a backed inode from an iag.
  *
  *             this routine performs the mechanics of allocating a
  *             specified inode from a backed extent.
@@ -2025,19 +2025,19 @@ static int diAllocExt(struct inomap * imap, int agno, struct inode *ip)
  *             in the face of updates to multiple buffers.  under this
  *             approach, all required buffers are obtained before making
  *             any updates and are held all are updates are complete.
- *             
+ *
  * PRE CONDITION: Already have buffer lock on iagp.  Already have AG lock on
  *     this AG.  Must have read lock on imap inode.
  *
  * PARAMETERS:
- *      imap   - pointer to inode map control structure.
- *      iagp   - pointer to iag. 
- *      ino    - inode number to be allocated within the iag.
+ *      imap   - pointer to inode map control structure.
+ *      iagp   - pointer to iag.
+ *      ino    - inode number to be allocated within the iag.
  *
  * RETURN VALUES:
  *      0       - success.
  *      -ENOSPC        - insufficient disk resources.
- *      -EIO   - i/o error.
+ *      -EIO   - i/o error.
  */
 static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino)
 {
@@ -2172,19 +2172,19 @@ static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino)
  *             buffers.  under this approach, all required buffers are
  *             obtained before making any updates and are held until all
  *             updates are complete.
- *             
+ *
  * PRE CONDITION: Already have buffer lock on iagp.  Already have AG lock on
  *     this AG.  Must have read lock on imap inode.
  *
  * PARAMETERS:
- *      imap   - pointer to inode map control structure.
- *      iagp   - pointer to iag. 
- *      extno          - extent number.
+ *      imap   - pointer to inode map control structure.
+ *      iagp   - pointer to iag.
+ *      extno  - extent number.
  *
  * RETURN VALUES:
  *      0       - success.
  *      -ENOSPC        - insufficient disk resources.
- *      -EIO   - i/o error.
+ *      -EIO   - i/o error.
  */
 static int diNewExt(struct inomap * imap, struct iag * iagp, int extno)
 {
@@ -2432,34 +2432,34 @@ static int diNewExt(struct inomap * imap, struct iag * iagp, int extno)
 /*
  * NAME:        diNewIAG(imap,iagnop,agno)
  *
- * FUNCTION:           allocate a new iag for an allocation group.
- *             
- *             first tries to allocate the iag from the inode map 
- *             iagfree list:  
- *             if the list has free iags, the head of the list is removed 
+ * FUNCTION:   allocate a new iag for an allocation group.
+ *
+ *             first tries to allocate the iag from the inode map
+ *             iagfree list:
+ *             if the list has free iags, the head of the list is removed
  *             and returned to satisfy the request.
  *             if the inode map's iag free list is empty, the inode map
  *             is extended to hold a new iag. this new iag is initialized
  *             and returned to satisfy the request.
  *
  * PARAMETERS:
- *      imap   - pointer to inode map control structure.
- *      iagnop         - pointer to an iag number set with the number of the
+ *      imap   - pointer to inode map control structure.
+ *      iagnop - pointer to an iag number set with the number of the
  *               newly allocated iag upon successful return.
- *      agno   - allocation group number.
+ *      agno   - allocation group number.
  *     bpp     - Buffer pointer to be filled in with new IAG's buffer
  *
  * RETURN VALUES:
  *      0       - success.
  *      -ENOSPC        - insufficient disk resources.
- *      -EIO   - i/o error.
+ *      -EIO   - i/o error.
  *
- * serialization: 
+ * serialization:
  *     AG lock held on entry/exit;
  *     write lock on the map is held inside;
  *     read lock on the map is held on successful completion;
  *
- * note: new iag transaction: 
+ * note: new iag transaction:
  * . synchronously write iag;
  * . write log of xtree and inode  of imap;
  * . commit;
@@ -2494,7 +2494,7 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
        /* acquire the free iag lock */
        IAGFREE_LOCK(imap);
 
-       /* if there are any iags on the inode map free iag list, 
+       /* if there are any iags on the inode map free iag list,
         * allocate the iag from the head of the list.
         */
        if (imap->im_freeiag >= 0) {
@@ -2618,8 +2618,8 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
                flush_metapage(mp);
 
                /*
-                * txCommit(COMMIT_FORCE) will synchronously write address 
-                * index pages and inode after commit in careful update order 
+                * txCommit(COMMIT_FORCE) will synchronously write address
+                * index pages and inode after commit in careful update order
                 * of address index pages (right to left, bottom up);
                 */
                iplist[0] = ipimap;
@@ -2678,11 +2678,11 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
  *
  * FUNCTION:    get the buffer for the specified iag within a fileset
  *             or aggregate inode map.
- *             
+ *
  * PARAMETERS:
- *      imap   - pointer to inode map control structure.
- *      iagno          - iag number.
- *      bpp    - point to buffer pointer to be filled in on successful
+ *      imap   - pointer to inode map control structure.
+ *      iagno  - iag number.
+ *      bpp    - point to buffer pointer to be filled in on successful
  *               exit.
  *
  * SERIALIZATION:
@@ -2692,7 +2692,7 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
  *
  * RETURN VALUES:
  *      0       - success.
- *      -EIO   - i/o error.
+ *      -EIO   - i/o error.
  */
 static int diIAGRead(struct inomap * imap, int iagno, struct metapage ** mpp)
 {
@@ -2718,8 +2718,8 @@ static int diIAGRead(struct inomap * imap, int iagno, struct metapage ** mpp)
  *             the specified bit position.
  *
  * PARAMETERS:
- *      word   - word to be examined.
- *      start          - starting bit position.
+ *      word   - word to be examined.
+ *      start  - starting bit position.
  *
  * RETURN VALUES:
  *      bit position of first free bit in the word or 32 if
@@ -2740,10 +2740,10 @@ static int diFindFree(u32 word, int start)
 
 /*
  * NAME:       diUpdatePMap()
- *                                                                    
- * FUNCTION: Update the persistent map in an IAG for the allocation or 
+ *
+ * FUNCTION: Update the persistent map in an IAG for the allocation or
  *     freeing of the specified inode.
- *                                                                    
+ *
  * PRE CONDITIONS: Working map has already been updated for allocate.
  *
  * PARAMETERS:
@@ -2752,7 +2752,7 @@ static int diFindFree(u32 word, int start)
  *     is_free - If 'true' indicates inode should be marked freed, otherwise
  *               indicates inode should be marked allocated.
  *
- * RETURN VALUES: 
+ * RETURN VALUES:
  *             0 for success
  */
 int
@@ -2793,7 +2793,7 @@ diUpdatePMap(struct inode *ipimap,
        extno = ino >> L2INOSPEREXT;
        bitno = ino & (INOSPEREXT - 1);
        mask = HIGHORDER >> bitno;
-       /* 
+       /*
         * mark the inode free in persistent map:
         */
        if (is_free) {
@@ -2803,7 +2803,7 @@ diUpdatePMap(struct inode *ipimap,
                 * of last reference release;
                 */
                if (!(le32_to_cpu(iagp->wmap[extno]) & mask)) {
-                       jfs_error(ipimap->i_sb, 
+                       jfs_error(ipimap->i_sb,
                                  "diUpdatePMap: inode %ld not marked as "
                                  "allocated in wmap!", inum);
                }
@@ -2877,8 +2877,8 @@ diUpdatePMap(struct inode *ipimap,
  *     diExtendFS()
  *
  * function: update imap for extendfs();
- * 
- * note: AG size has been increased s.t. each k old contiguous AGs are 
+ *
+ * note: AG size has been increased s.t. each k old contiguous AGs are
  * coalesced into a new AG;
  */
 int diExtendFS(struct inode *ipimap, struct inode *ipbmap)
@@ -2897,7 +2897,7 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap)
                   atomic_read(&imap->im_numfree));
 
        /*
-        *      reconstruct imap 
+        *      reconstruct imap
         *
         * coalesce contiguous k (newAGSize/oldAGSize) AGs;
         * i.e., (AGi, ..., AGj) where i = k*n and j = k*(n+1) - 1 to AGn;
@@ -2931,7 +2931,7 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap)
                }
 
                /* leave free iag in the free iag list */
-               if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {  
+               if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {
                        release_metapage(bp);
                        continue;
                }
index e3b7db47db6bb31e6acd06b927e70a0a978bf112..4f9c346ed49868eaa6f9546a3be6299bdac0c294 100644 (file)
@@ -1,18 +1,18 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2002
+ *   Copyright (C) International Business Machines Corp., 2000-2002
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef        _H_JFS_IMAP
 /* get the starting block number of the 4K page of an inode extent
  * that contains ino.
  */
-#define INOPBLK(pxd,ino,l2nbperpg)     (addressPXD((pxd)) +            \
+#define INOPBLK(pxd,ino,l2nbperpg)     (addressPXD((pxd)) +            \
        ((((ino) & (INOSPEREXT-1)) >> L2INOSPERPAGE) << (l2nbperpg)))
 
 /*
  *     inode allocation map:
- * 
- * inode allocation map consists of 
+ *
+ * inode allocation map consists of
  * . the inode map control page and
  * . inode allocation group pages (per 4096 inodes)
  * which are addressed by standard JFS xtree.
index 54d73716ca8c4dfbed653ae6e0c0df29dcb6da96..94005584445a403f00996cd3d3bc50cec9d0679f 100644 (file)
@@ -4,18 +4,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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */ 
+ */
 #ifndef _H_JFS_INCORE
 #define _H_JFS_INCORE
 
index bffaca9ae3a20ef31e737485230b0836d666887a..4c67ed97682b74711ce67fcd37681e5b4e26fb20 100644 (file)
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -61,7 +61,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
        inode = new_inode(sb);
        if (!inode) {
                jfs_warn("ialloc: new_inode returned NULL!");
-               return inode;
+               return ERR_PTR(-ENOMEM);
        }
 
        jfs_inode = JFS_IP(inode);
@@ -69,9 +69,10 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
        rc = diAlloc(parent, S_ISDIR(mode), inode);
        if (rc) {
                jfs_warn("ialloc: diAlloc returned %d!", rc);
-               make_bad_inode(inode);
+               if (rc == -EIO)
+                       make_bad_inode(inode);
                iput(inode);
-               return NULL;
+               return ERR_PTR(rc);
        }
 
        inode->i_uid = current->fsuid;
@@ -97,7 +98,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
                inode->i_flags |= S_NOQUOTA;
                inode->i_nlink = 0;
                iput(inode);
-               return NULL;
+               return ERR_PTR(-EDQUOT);
        }
 
        inode->i_mode = mode;
index 1fc48df670c834f334f9620c4bd44c0a586145c7..0d06ccfaff0e7cf69935e556643f6176c99d4c4b 100644 (file)
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef        _H_JFS_INODE
index 70ac9f7d1e00c22064dcc43ff3d923820ce1048c..7d78e83d7c40eaee39c0b9e67b6210b5ea40504c 100644 (file)
@@ -1,19 +1,19 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2001
- *   Portions Copyright (c) Christoph Hellwig, 2001-2002
+ *   Copyright (C) International Business Machines Corp., 2000-2001
+ *   Portions Copyright (C) Christoph Hellwig, 2001-2002
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef _H_JFS_LOCK
index 3315f0b1fbc0ad5106e28dd65369ac7e443739e1..b89c9aba046635b90ec977a9415ddb8ef79a2f8f 100644 (file)
@@ -4,16 +4,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -337,7 +337,7 @@ int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
  * PARAMETER:  cd      - commit descriptor
  *
  * RETURN:     end-of-log address
- *                     
+ *
  * serialization: LOG_LOCK() held on entry/exit
  */
 static int
@@ -554,7 +554,7 @@ lmWriteRecord(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
  * PARAMETER:  log
  *
  * RETURN:     0
- *                     
+ *
  * serialization: LOG_LOCK() held on entry/exit
  */
 static int lmNextPage(struct jfs_log * log)
@@ -656,7 +656,7 @@ static int lmNextPage(struct jfs_log * log)
  *     page number - redrive pageout of the page at the head of
  *     pageout queue until full page has been written.
  *
- * RETURN:     
+ * RETURN:
  *
  * NOTE:
  *     LOGGC_LOCK serializes log group commit queue, and
@@ -920,10 +920,10 @@ static void lmPostGC(struct lbuf * bp)
  *     this code is called again.
  *
  * PARAMETERS: log     - log structure
- *             hard_sync - 1 to force all metadata to be written
+ *             hard_sync - 1 to force all metadata to be written
  *
  * RETURN:     0
- *                     
+ *
  * serialization: LOG_LOCK() held on entry/exit
  */
 static int lmLogSync(struct jfs_log * log, int hard_sync)
@@ -1052,7 +1052,7 @@ static int lmLogSync(struct jfs_log * log, int hard_sync)
  * FUNCTION:   write log SYNCPT record for specified log
  *
  * PARAMETERS: log       - log structure
- *             hard_sync - set to 1 to force metadata to be written
+ *             hard_sync - set to 1 to force metadata to be written
  */
 void jfs_syncpt(struct jfs_log *log, int hard_sync)
 {      LOG_LOCK(log);
@@ -1067,7 +1067,7 @@ void jfs_syncpt(struct jfs_log *log, int hard_sync)
  *     insert filesystem in the active list of the log.
  *
  * PARAMETER:  ipmnt   - file system mount inode
- *             iplog   - log inode (out)
+ *             iplog   - log inode (out)
  *
  * RETURN:
  *
@@ -1082,7 +1082,7 @@ int lmLogOpen(struct super_block *sb)
 
        if (sbi->flag & JFS_NOINTEGRITY)
                return open_dummy_log(sb);
-       
+
        if (sbi->mntflag & JFS_INLINELOG)
                return open_inline_log(sb);
 
@@ -1131,7 +1131,7 @@ int lmLogOpen(struct super_block *sb)
 
        log->bdev = bdev;
        memcpy(log->uuid, sbi->loguuid, sizeof(log->uuid));
-       
+
        /*
         * initialize log:
         */
@@ -1253,13 +1253,13 @@ static int open_dummy_log(struct super_block *sb)
  *     initialize the log from log superblock.
  *     set the log state in the superblock to LOGMOUNT and
  *     write SYNCPT log record.
- *             
+ *
  * PARAMETER:  log     - log structure
  *
  * RETURN:     0       - if ok
  *             -EINVAL - bad log magic number or superblock dirty
  *             error returned from logwait()
- *                     
+ *
  * serialization: single first open thread
  */
 int lmLogInit(struct jfs_log * log)
@@ -1297,7 +1297,7 @@ int lmLogInit(struct jfs_log * log)
 
        if (!test_bit(log_INLINELOG, &log->flag))
                log->l2bsize = L2LOGPSIZE;
-       
+
        /* check for disabled journaling to disk */
        if (log->no_integrity) {
                /*
@@ -1651,7 +1651,7 @@ void jfs_flush_journal(struct jfs_log *log, int wait)
  * PARAMETER:  log     - log inode
  *
  * RETURN:     0       - success
- *                     
+ *
  * serialization: single last close thread
  */
 int lmLogShutdown(struct jfs_log * log)
@@ -1677,7 +1677,7 @@ int lmLogShutdown(struct jfs_log * log)
        lrd.type = cpu_to_le16(LOG_SYNCPT);
        lrd.length = 0;
        lrd.log.syncpt.sync = 0;
-       
+
        lsn = lmWriteRecord(log, NULL, &lrd, NULL);
        bp = log->bp;
        lp = (struct logpage *) bp->l_ldata;
@@ -1703,7 +1703,7 @@ int lmLogShutdown(struct jfs_log * log)
        jfs_info("lmLogShutdown: lsn:0x%x page:%d eor:%d",
                 lsn, log->page, log->eor);
 
-      out:    
+      out:
        /*
         * shutdown per log i/o
         */
@@ -1769,7 +1769,7 @@ static int lmLogFileSystem(struct jfs_log * log, struct jfs_sb_info *sbi,
                        lbmFree(bpsuper);
                        return -EIO;
                }
-               
+
        }
 
        /*
index 8c6909b80014b6948c0f044cb19062e72fafe25d..a53fb17ea219eeb8bc6e0bd903954b0fa0e724f6 100644 (file)
@@ -4,16 +4,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef        _H_JFS_LOGMGR
 /*
  *     log logical volume
  *
- * a log is used to make the commit operation on journalled 
+ * a log is used to make the commit operation on journalled
  * files within the same logical volume group atomic.
  * a log is implemented with a logical volume.
- * there is one log per logical volume group. 
+ * there is one log per logical volume group.
  *
  * block 0 of the log logical volume is not used (ipl etc).
  * block 1 contains a log "superblock" and is used by logFormat(),
- * lmLogInit(), lmLogShutdown(), and logRedo() to record status 
- * of the log but is not otherwise used during normal processing. 
+ * lmLogInit(), lmLogShutdown(), and logRedo() to record status
+ * of the log but is not otherwise used during normal processing.
  * blocks 2 - (N-1) are used to contain log records.
  *
- * when a volume group is varied-on-line, logRedo() must have 
- * been executed before the file systems (logical volumes) in 
+ * when a volume group is varied-on-line, logRedo() must have
+ * been executed before the file systems (logical volumes) in
  * the volume group can be mounted.
  */
 /*
@@ -97,26 +97,26 @@ struct logsuper {
  *     log logical page
  *
  * (this comment should be rewritten !)
- * the header and trailer structures (h,t) will normally have 
+ * the header and trailer structures (h,t) will normally have
  * the same page and eor value.
- * An exception to this occurs when a complete page write is not 
+ * An exception to this occurs when a complete page write is not
  * accomplished on a power failure. Since the hardware may "split write"
- * sectors in the page, any out of order sequence may occur during powerfail 
+ * sectors in the page, any out of order sequence may occur during powerfail
  * and needs to be recognized during log replay.  The xor value is
  * an "exclusive or" of all log words in the page up to eor.  This
  * 32 bit eor is stored with the top 16 bits in the header and the
  * bottom 16 bits in the trailer.  logredo can easily recognize pages
- * that were not completed by reconstructing this eor and checking 
+ * that were not completed by reconstructing this eor and checking
  * the log page.
  *
- * Previous versions of the operating system did not allow split 
- * writes and detected partially written records in logredo by 
- * ordering the updates to the header, trailer, and the move of data 
- * into the logdata area.  The order: (1) data is moved (2) header 
- * is updated (3) trailer is updated.  In logredo, when the header 
- * differed from the trailer, the header and trailer were reconciled 
- * as follows: if h.page != t.page they were set to the smaller of 
- * the two and h.eor and t.eor set to 8 (i.e. empty page). if (only) 
+ * Previous versions of the operating system did not allow split
+ * writes and detected partially written records in logredo by
+ * ordering the updates to the header, trailer, and the move of data
+ * into the logdata area.  The order: (1) data is moved (2) header
+ * is updated (3) trailer is updated.  In logredo, when the header
+ * differed from the trailer, the header and trailer were reconciled
+ * as follows: if h.page != t.page they were set to the smaller of
+ * the two and h.eor and t.eor set to 8 (i.e. empty page). if (only)
  * h.eor != t.eor they were set to the smaller of their two values.
  */
 struct logpage {
@@ -147,20 +147,20 @@ struct logpage {
  * in a  page, pages are written to temporary paging space if
  * if they must be written to disk before commit, and i/o is
  * scheduled for modified pages to their home location after
- * the log records containing the after values and the commit 
+ * the log records containing the after values and the commit
  * record is written to the log on disk, undo discards the copy
  * in main-memory.)
  *
- * a log record consists of a data area of variable length followed by 
+ * a log record consists of a data area of variable length followed by
  * a descriptor of fixed size LOGRDSIZE bytes.
- * the  data area is rounded up to an integral number of 4-bytes and 
+ * the  data area is rounded up to an integral number of 4-bytes and
  * must be no longer than LOGPSIZE.
- * the descriptor is of size of multiple of 4-bytes and aligned on a 
- * 4-byte boundary. 
+ * the descriptor is of size of multiple of 4-bytes and aligned on a
+ * 4-byte boundary.
  * records are packed one after the other in the data area of log pages.
- * (sometimes a DUMMY record is inserted so that at least one record ends 
+ * (sometimes a DUMMY record is inserted so that at least one record ends
  * on every page or the longest record is placed on at most two pages).
- * the field eor in page header/trailer points to the byte following 
+ * the field eor in page header/trailer points to the byte following
  * the last record on a page.
  */
 
@@ -270,11 +270,11 @@ struct lrd {
                /*
                 *      NOREDOINOEXT: the inode extent is freed
                 *
-                * do not apply after-image records which precede this 
-                * record in the log with the any of the 4 page block 
-                * numbers in this inode extent. 
-                * 
-                * NOTE: The fileset and pxd fields MUST remain in 
+                * do not apply after-image records which precede this
+                * record in the log with the any of the 4 page block
+                * numbers in this inode extent.
+                *
+                * NOTE: The fileset and pxd fields MUST remain in
                 *       the same fields in the REDOPAGE record format.
                 *
                 */
@@ -319,12 +319,10 @@ struct lrd {
                 * do not apply records which precede this record in the log
                 * with the same inode number.
                 *
-                * NOREDILE must be the first to be written at commit
+                * NOREDOFILE must be the first to be written at commit
                 * (last to be read in logredo()) - it prevents
                 * replay of preceding updates of all preceding generations
-                * of the inumber esp. the on-disk inode itself, 
-                * but does NOT prevent
-                * replay of the 
+                * of the inumber esp. the on-disk inode itself.
                 */
                struct {
                        __le32 fileset; /* 4: fileset number */
@@ -332,7 +330,7 @@ struct lrd {
                } noredofile;
 
                /*
-                *      ? NEWPAGE: 
+                *      ? NEWPAGE:
                 *
                 * metadata type dependent
                 */
@@ -464,7 +462,7 @@ struct lbuf {
        s64 l_blkno;            /* 8: log page block number */
        caddr_t l_ldata;        /* 4: data page */
        struct page *l_page;    /* The page itself */
-       uint l_offset;          /* Offset of l_ldata within the page */ 
+       uint l_offset;          /* Offset of l_ldata within the page */
 
        wait_queue_head_t l_ioevent;    /* 4: i/o done event */
 };
index f5afc129d6b12d2c9483574441f7b7296fb15cac..0cccd1c39d750e199185c4b1d7f7004f52246142 100644 (file)
@@ -4,16 +4,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -461,7 +461,7 @@ static int metapage_writepage(struct page *page, struct writeback_control *wbc)
                                goto add_failed;
                if (!bio->bi_size)
                        goto dump_bio;
-               
+
                submit_bio(WRITE, bio);
        }
        if (redirty)
@@ -648,7 +648,7 @@ struct metapage *__get_metapage(struct inode *inode, unsigned long lblock,
                        jfs_err("logical_size = %d, size = %d",
                                mp->logical_size, size);
                        dump_stack();
-                       goto unlock; 
+                       goto unlock;
                }
                mp->count++;
                lock_metapage(mp);
@@ -658,7 +658,7 @@ struct metapage *__get_metapage(struct inode *inode, unsigned long lblock,
                                          "__get_metapage: using a "
                                          "discarded metapage");
                                discard_metapage(mp);
-                               goto unlock; 
+                               goto unlock;
                        }
                        clear_bit(META_discard, &mp->flag);
                }
index 01a5a455e012709d95b55f2a45e41e7bac5c879e..d94f8d9e87d79daf92e639c791a3b81742eadb57 100644 (file)
@@ -4,16 +4,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef        _H_JFS_METAPAGE
@@ -33,7 +33,7 @@ struct metapage {
        unsigned long flag;     /* See Below */
        unsigned long count;    /* Reference count */
        void *data;             /* Data pointer */
-       sector_t index;         /* block address of page */
+       sector_t index;         /* block address of page */
        wait_queue_head_t wait;
 
        /* implementation */
index 032d111bc3309b65f4f3a8c80e5556c1a3435afb..4dd479834897be20d7e8ee4d5b7b66eccf1d0137 100644 (file)
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
  *
  * note: file system in transition to aggregate/fileset:
  *
- * file system mount is interpreted as the mount of aggregate, 
- * if not already mounted, and mount of the single/only fileset in 
+ * file system mount is interpreted as the mount of aggregate,
+ * if not already mounted, and mount of the single/only fileset in
  * the aggregate;
  *
  * a file system/aggregate is represented by an internal inode
  * (aka mount inode) initialized with aggregate superblock;
- * each vfs represents a fileset, and points to its "fileset inode 
+ * each vfs represents a fileset, and points to its "fileset inode
  * allocation map inode" (aka fileset inode):
- * (an aggregate itself is structured recursively as a filset: 
- * an internal vfs is constructed and points to its "fileset inode 
- * allocation map inode" (aka aggregate inode) where each inode 
- * represents a fileset inode) so that inode number is mapped to 
+ * (an aggregate itself is structured recursively as a filset:
+ * an internal vfs is constructed and points to its "fileset inode
+ * allocation map inode" (aka aggregate inode) where each inode
+ * represents a fileset inode) so that inode number is mapped to
  * on-disk inode in uniform way at both aggregate and fileset level;
  *
  * each vnode/inode of a fileset is linked to its vfs (to facilitate
@@ -41,7 +41,7 @@
  * per aggregate information, e.g., block size, etc.) as well as
  * its file set inode.
  *
- *   aggregate 
+ *   aggregate
  *   ipmnt
  *   mntvfs -> fileset ipimap+ -> aggregate ipbmap -> aggregate ipaimap;
  *             fileset vfs     -> vp(1) <-> ... <-> vp(n) <->vproot;
@@ -88,7 +88,7 @@ int jfs_mount(struct super_block *sb)
        struct inode *ipbmap = NULL;
 
        /*
-        * read/validate superblock 
+        * read/validate superblock
         * (initialize mount inode from the superblock)
         */
        if ((rc = chkSuper(sb))) {
@@ -238,7 +238,7 @@ int jfs_mount(struct super_block *sb)
  */
 int jfs_mount_rw(struct super_block *sb, int remount)
 {
-       struct jfs_sb_info *sbi = JFS_SBI(sb);  
+       struct jfs_sb_info *sbi = JFS_SBI(sb);
        int rc;
 
        /*
@@ -291,7 +291,7 @@ int jfs_mount_rw(struct super_block *sb, int remount)
 /*
  *     chkSuper()
  *
- * validate the superblock of the file system to be mounted and 
+ * validate the superblock of the file system to be mounted and
  * get the file system parameters.
  *
  * returns
@@ -426,7 +426,7 @@ int updateSuper(struct super_block *sb, uint state)
                        jfs_err("updateSuper: bad state");
        } else if (sbi->state == FM_DIRTY)
                return 0;
-       
+
        if ((rc = readSuper(sb, &bh)))
                return rc;
 
@@ -486,9 +486,9 @@ int readSuper(struct super_block *sb, struct buffer_head **bpp)
  * for this file system past this point in log.
  * it is harmless if mount fails.
  *
- * note: MOUNT record is at aggregate level, not at fileset level, 
+ * note: MOUNT record is at aggregate level, not at fileset level,
  * since log records of previous mounts of a fileset
- * (e.g., AFTER record of extent allocation) have to be processed 
+ * (e.g., AFTER record of extent allocation) have to be processed
  * to update block allocation map at aggregate level.
  */
 static int logMOUNT(struct super_block *sb)
index 682cf1a68a185ae3a7f22c954a86de1b35c2d339..884fc21ab8ee6182bb0d8ea3f58450b78895a277 100644 (file)
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef        _H_JFS_SUPERBLOCK
 /*
  * make the magic number something a human could read
  */
-#define JFS_MAGIC      "JFS1"  /* Magic word */
+#define JFS_MAGIC      "JFS1"  /* Magic word */
 
 #define JFS_VERSION    2       /* Version number: Version 2 */
 
 #define LV_NAME_SIZE   11      /* MUST BE 11 for OS/2 boot sector */
 
-/* 
- *     aggregate superblock 
+/*
+ *     aggregate superblock
  *
  * The name superblock is too close to super_block, so the name has been
  * changed to jfs_superblock.  The utilities are still using the old name.
@@ -40,7 +40,7 @@ struct jfs_superblock {
        __le64 s_size;          /* 8: aggregate size in hardware/LVM blocks;
                                 * VFS: number of blocks
                                 */
-       __le32 s_bsize;         /* 4: aggregate block size in bytes; 
+       __le32 s_bsize;         /* 4: aggregate block size in bytes;
                                 * VFS: fragment size
                                 */
        __le16 s_l2bsize;       /* 2: log2 of s_bsize */
@@ -54,7 +54,7 @@ struct jfs_superblock {
        __le32 s_flag;          /* 4: aggregate attributes:
                                 *    see jfs_filsys.h
                                 */
-       __le32 s_state;         /* 4: mount/unmount/recovery state: 
+       __le32 s_state;         /* 4: mount/unmount/recovery state:
                                 *    see jfs_filsys.h
                                 */
        __le32 s_compress;              /* 4: > 0 if data compression */
@@ -75,11 +75,11 @@ struct jfs_superblock {
        struct timestruc_t s_time;      /* 8: time last updated */
 
        __le32 s_fsckloglen;    /* 4: Number of filesystem blocks reserved for
-                                *    the fsck service log.  
+                                *    the fsck service log.
                                 *    N.B. These blocks are divided among the
                                 *         versions kept.  This is not a per
                                 *         version size.
-                                *    N.B. These blocks are included in the 
+                                *    N.B. These blocks are included in the
                                 *         length field of s_fsckpxd.
                                 */
        s8 s_fscklog;           /* 1: which fsck service log is most recent
@@ -87,7 +87,7 @@ struct jfs_superblock {
                                 *    1 => the first one
                                 *    2 => the 2nd one
                                 */
-       char s_fpack[11];       /* 11: file system volume name 
+       char s_fpack[11];       /* 11: file system volume name
                                 *     N.B. This must be 11 bytes to
                                 *          conform with the OS/2 BootSector
                                 *          requirements
index ebfa6c061d78c5e7ff4755522291b38ca7278d38..81f6f04af192ae45c64d3022591522b527342a38 100644 (file)
@@ -4,16 +4,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -2026,8 +2026,6 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
                 * truncate entry XAD[twm == next - 1]:
                 */
                if (twm == next - 1) {
-                       struct pxd_lock *pxdlock;
-
                        /* format a maplock for txUpdateMap() to update bmap
                         * to free truncated delta extent of the truncated
                         * entry XAD[next - 1];
index 0e4dc4514c47a4953420fa1cb1f9201b19ca6da1..7863cf21afcac82ef586c97541697f14d2640eaa 100644 (file)
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef _H_JFS_TXNMGR
@@ -179,7 +179,7 @@ struct linelock {
        /* (8) */
 
        struct lv lv[20];       /* 40: */
-};                             /* (48) */
+};                             /* (48) */
 
 #define dt_lock        linelock
 
@@ -211,8 +211,8 @@ struct xtlock {
  * at tlock.lock/linelock: watch for alignment;
  * N.B. next field may be set by linelock, and should not
  * be modified by maplock;
- * N.B. index of the first pxdlock specifies index of next 
- * free maplock (i.e., number of maplock) in the tlock; 
+ * N.B. index of the first pxdlock specifies index of next
+ * free maplock (i.e., number of maplock) in the tlock;
  */
 struct maplock {
        lid_t next;             /* 2: */
index 21eaf7ac0fcb6c46ebfc784bc9a9a24a32e18339..a386f48c73fcb5270bfcf90ac067d172792280f6 100644 (file)
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -22,8 +22,8 @@
  * note: file system in transition to aggregate/fileset:
  * (ref. jfs_mount.c)
  *
- * file system unmount is interpreted as mount of the single/only 
- * fileset in the aggregate and, if unmount of the last fileset, 
+ * file system unmount is interpreted as mount of the single/only
+ * fileset in the aggregate and, if unmount of the last fileset,
  * as unmount of the aggerate;
  */
 
@@ -60,13 +60,13 @@ int jfs_umount(struct super_block *sb)
        jfs_info("UnMount JFS: sb:0x%p", sb);
 
        /*
-        *      update superblock and close log 
+        *      update superblock and close log
         *
         * if mounted read-write and log based recovery was enabled
         */
        if ((log = sbi->log))
                /*
-                * Wait for outstanding transactions to be written to log: 
+                * Wait for outstanding transactions to be written to log:
                 */
                jfs_flush_journal(log, 2);
 
@@ -112,17 +112,17 @@ int jfs_umount(struct super_block *sb)
 
        /*
         * ensure all file system file pages are propagated to their
-        * home blocks on disk (and their in-memory buffer pages are 
+        * home blocks on disk (and their in-memory buffer pages are
         * invalidated) BEFORE updating file system superblock state
-        * (to signify file system is unmounted cleanly, and thus in 
-        * consistent state) and log superblock active file system 
+        * (to signify file system is unmounted cleanly, and thus in
+        * consistent state) and log superblock active file system
         * list (to signify skip logredo()).
         */
        if (log) {              /* log = NULL if read-only mount */
                updateSuper(sb, FM_CLEAN);
 
                /*
-                * close log: 
+                * close log:
                 *
                 * remove file system from log active file system list.
                 */
@@ -142,7 +142,7 @@ int jfs_umount_rw(struct super_block *sb)
                return 0;
 
        /*
-        * close log: 
+        * close log:
         *
         * remove file system from log active file system list.
         */
index f327decfb1556c5abb146e999bf1bd1cb94b4a6b..c7de6f5bbefc1da43b269ffe54ddec707ba7b0a1 100644 (file)
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -57,8 +57,8 @@ int jfs_strfromUCS_le(char *to, const __le16 * from,
                                        warn--;
                                        warn_again--;
                                        printk(KERN_ERR
-                       "non-latin1 character 0x%x found in JFS file name\n", 
-                                              le16_to_cpu(from[i]));
+                       "non-latin1 character 0x%x found in JFS file name\n",
+                                              le16_to_cpu(from[i]));
                                        printk(KERN_ERR
                                "mount with iocharset=utf8 to access\n");
                                }
@@ -124,7 +124,7 @@ int get_UCSname(struct component_name * uniName, struct dentry *dentry)
            kmalloc((length + 1) * sizeof(wchar_t), GFP_NOFS);
 
        if (uniName->name == NULL)
-               return -ENOSPC;
+               return -ENOMEM;
 
        uniName->namlen = jfs_strtoUCS(uniName->name, dentry->d_name.name,
                                       length, nls_tab);
index 69e25ebe87ac94cb222955b272cc5430ddc13a0f..3fbb3a22559077e0fbfd21ae4a44cb91ebd7605e 100644 (file)
@@ -1,19 +1,19 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2002
- *   Portions Copyright (c) Christoph Hellwig, 2001-2002
+ *   Copyright (C) International Business Machines Corp., 2000-2002
+ *   Portions Copyright (C) Christoph Hellwig, 2001-2002
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef _H_JFS_UNICODE
index 4ab185d26308b9f081e360ee32697d3c3d1c0516..cfe50666d31220893c4b35a8fe2b111e2be5bb94 100644 (file)
@@ -1,18 +1,18 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2002
+ *   Copyright (C) International Business Machines Corp., 2000-2002
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
index 25e9990bccd1be1926a21847d4135544a7dd4e42..88b6cc535bf246cee2dc33487993fcd488b48dc2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2002
+ *   Copyright (C) International Business Machines Corp., 2000-2002
  *
  *   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
index c92307d3a57ea21480d9081586da1ca00da15011..e98eb03e53105083b3fb33b0c35b11a3c5b3f8f3 100644 (file)
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 /*
@@ -2428,7 +2428,7 @@ printf("xtUpdate.updateLeft.split p:0x%p\n", p);
  * return:
  */
 int xtAppend(tid_t tid,                /* transaction id */
-            struct inode *ip, int xflag, s64 xoff, s32 maxblocks,      
+            struct inode *ip, int xflag, s64 xoff, s32 maxblocks,
             s32 * xlenp,       /* (in/out) */
             s64 * xaddrp,      /* (in/out) */
             int flag)
@@ -2499,7 +2499,7 @@ int xtAppend(tid_t tid,           /* transaction id */
        pxdlist.maxnpxd = pxdlist.npxd = 0;
        pxd = &pxdlist.pxd[0];
        nblocks = JFS_SBI(ip->i_sb)->nbperpage;
-       for (; nsplit > 0; nsplit--, pxd++, xaddr += nblocks, maxblocks -= nblocks) {   
+       for (; nsplit > 0; nsplit--, pxd++, xaddr += nblocks, maxblocks -= nblocks) {
                if ((rc = dbAllocBottomUp(ip, xaddr, (s64) nblocks)) == 0) {
                        PXDaddress(pxd, xaddr);
                        PXDlength(pxd, nblocks);
@@ -2514,7 +2514,7 @@ int xtAppend(tid_t tid,           /* transaction id */
                goto out;
        }
 
-       xlen = min(xlen, maxblocks);    
+       xlen = min(xlen, maxblocks);
 
        /*
         * allocate data extent requested
index af668a80b40f8b989d278f7fdc0068b73bc41ef6..164f6f2b10191055bdb10522e9d1ff17603f3df5 100644 (file)
@@ -1,18 +1,18 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2002
+ *   Copyright (C) International Business Machines Corp., 2000-2002
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef _H_JFS_XTREE
index b8d16a6aa88f0c7c11f4bb741f671bba40ac51c6..a6a8c16c872c886ba68f3e89c7d2682a1e9d429f 100644 (file)
@@ -4,16 +4,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -41,7 +41,7 @@ static s64 commitZeroLink(tid_t, struct inode *);
 /*
  * NAME:       free_ea_wmap(inode)
  *
- * FUNCTION:   free uncommitted extended attributes from working map 
+ * FUNCTION:   free uncommitted extended attributes from working map
  *
  */
 static inline void free_ea_wmap(struct inode *inode)
@@ -62,7 +62,7 @@ static inline void free_ea_wmap(struct inode *inode)
  * FUNCTION:   create a regular file in the parent directory <dip>
  *             with name = <from dentry> and mode = <mode>
  *
- * PARAMETER:  dip     - parent directory vnode
+ * PARAMETER:  dip     - parent directory vnode
  *             dentry  - dentry of new file
  *             mode    - create mode (rwxrwxrwx).
  *             nd- nd struct
@@ -97,8 +97,8 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
         * begin the transaction before we search the directory.
         */
        ip = ialloc(dip, mode);
-       if (ip == NULL) {
-               rc = -ENOSPC;
+       if (IS_ERR(ip)) {
+               rc = PTR_ERR(ip);
                goto out2;
        }
 
@@ -190,7 +190,7 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
  * FUNCTION:   create a child directory in the parent directory <dip>
  *             with name = <from dentry> and mode = <mode>
  *
- * PARAMETER:  dip     - parent directory vnode
+ * PARAMETER:  dip     - parent directory vnode
  *             dentry  - dentry of child directory
  *             mode    - create mode (rwxrwxrwx).
  *
@@ -231,8 +231,8 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
         * begin the transaction before we search the directory.
         */
        ip = ialloc(dip, S_IFDIR | mode);
-       if (ip == NULL) {
-               rc = -ENOSPC;
+       if (IS_ERR(ip)) {
+               rc = PTR_ERR(ip);
                goto out2;
        }
 
@@ -324,7 +324,7 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
  *
  * FUNCTION:   remove a link to child directory
  *
- * PARAMETER:  dip     - parent inode
+ * PARAMETER:  dip     - parent inode
  *             dentry  - child directory dentry
  *
  * RETURN:     -EINVAL - if name is . or ..
@@ -332,10 +332,10 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
  *             errors from subroutines
  *
  * note:
- * if other threads have the directory open when the last link 
- * is removed, the "." and ".." entries, if present, are removed before 
- * rmdir() returns and no new entries may be created in the directory, 
- * but the directory is not removed until the last reference to 
+ * if other threads have the directory open when the last link
+ * is removed, the "." and ".." entries, if present, are removed before
+ * rmdir() returns and no new entries may be created in the directory,
+ * but the directory is not removed until the last reference to
  * the directory is released (cf.unlink() of regular file).
  */
 static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
@@ -446,11 +446,11 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
 /*
  * NAME:       jfs_unlink(dip, dentry)
  *
- * FUNCTION:   remove a link to object <vp> named by <name> 
+ * FUNCTION:   remove a link to object <vp> named by <name>
  *             from parent directory <dvp>
  *
- * PARAMETER:  dip     - inode of parent directory
- *             dentry  - dentry of object to be removed
+ * PARAMETER:  dip     - inode of parent directory
+ *             dentry  - dentry of object to be removed
  *
  * RETURN:     errors from subroutines
  *
@@ -598,7 +598,7 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
  *
  * FUNCTION:    for non-directory, called by jfs_remove(),
  *             truncate a regular file, directory or symbolic
- *             link to zero length. return 0 if type is not 
+ *             link to zero length. return 0 if type is not
  *             one of these.
  *
  *             if the file is currently associated with a VM segment
@@ -608,7 +608,7 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
  *             map by ctrunc1.
  *             if there is no VM segment on entry, the resources are
  *             freed in both work and permanent map.
- *             (? for temporary file - memory object is cached even 
+ *             (? for temporary file - memory object is cached even
  *             after no reference:
  *             reference count > 0 -   )
  *
@@ -662,7 +662,7 @@ static s64 commitZeroLink(tid_t tid, struct inode *ip)
 
        /*
         * free xtree/data (truncate to zero length):
-        * free xtree/data pages from cache if COMMIT_PWMAP, 
+        * free xtree/data pages from cache if COMMIT_PWMAP,
         * free xtree/data blocks from persistent block map, and
         * free xtree/data blocks from working block map if COMMIT_PWMAP;
         */
@@ -677,7 +677,7 @@ static s64 commitZeroLink(tid_t tid, struct inode *ip)
  * NAME:       jfs_free_zero_link()
  *
  * FUNCTION:    for non-directory, called by iClose(),
- *             free resources of a file from cache and WORKING map 
+ *             free resources of a file from cache and WORKING map
  *             for a file previously committed with zero link count
  *             while associated with a pager object,
  *
@@ -762,7 +762,7 @@ void jfs_free_zero_link(struct inode *ip)
  * FUNCTION:   create a link to <vp> by the name = <name>
  *             in the parent directory <dvp>
  *
- * PARAMETER:  vp      - target object
+ * PARAMETER:  vp      - target object
  *             dvp     - parent directory of new link
  *             name    - name of new link to target object
  *             crp     - credential
@@ -858,8 +858,8 @@ static int jfs_link(struct dentry *old_dentry,
  *                     in directory <dip>
  *
  * PARAMETER:  dip         - parent directory vnode
- *                     dentry  - dentry of symbolic link
- *                     name    - the path name of the existing object 
+ *                     dentry  - dentry of symbolic link
+ *                     name    - the path name of the existing object
  *                                   that will be the source of the link
  *
  * RETURN:     errors from subroutines
@@ -906,8 +906,8 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
         * (iAlloc() returns new, locked inode)
         */
        ip = ialloc(dip, S_IFLNK | 0777);
-       if (ip == NULL) {
-               rc = -ENOSPC;
+       if (IS_ERR(ip)) {
+               rc = PTR_ERR(ip);
                goto out2;
        }
 
@@ -926,7 +926,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
        tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
 
        /* fix symlink access permission
-        * (dir_create() ANDs in the u.u_cmask, 
+        * (dir_create() ANDs in the u.u_cmask,
         * but symlinks really need to be 777 access)
         */
        ip->i_mode |= 0777;
@@ -967,7 +967,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
                ip->i_mapping->a_ops = &jfs_aops;
 
                /*
-                * even though the data of symlink object (source 
+                * even though the data of symlink object (source
                 * path name) is treated as non-journaled user data,
                 * it is read/written thru buffer cache for performance.
                 */
@@ -978,7 +978,6 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
                xlen = xsize >> JFS_SBI(sb)->l2bsize;
                if ((rc = xtInsert(tid, ip, 0, 0, xlen, &xaddr, 0))) {
                        txAbort(tid, 0);
-                       rc = -ENOSPC;
                        goto out3;
                }
                extent = xaddr;
@@ -1176,7 +1175,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                        /* free block resources */
                        if ((new_size = commitZeroLink(tid, new_ip)) < 0) {
                                txAbort(tid, 1);        /* Marks FS Dirty */
-                               rc = new_size;          
+                               rc = new_size;
                                goto out4;
                        }
                        tblk = tid_to_tblock(tid);
@@ -1292,7 +1291,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                new_size = xtTruncate_pmap(tid, new_ip, new_size);
                if (new_size < 0) {
                        txAbort(tid, 1);
-                       rc = new_size;          
+                       rc = new_size;
                } else
                        rc = txCommit(tid, 1, &new_ip, COMMIT_SYNC);
                txEnd(tid);
@@ -1350,8 +1349,8 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry,
                goto out;
 
        ip = ialloc(dir, mode);
-       if (ip == NULL) {
-               rc = -ENOSPC;
+       if (IS_ERR(ip)) {
+               rc = PTR_ERR(ip);
                goto out1;
        }
        jfs_ip = JFS_IP(ip);
index 45180361871c9a98e04db73506a973e0c0dce0c1..79d625f3f7336f555acb604ca30966819b97e5d0 100644 (file)
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
 
index 143bcd1d5eaa42f0529596676c85c16304a3e995..9c1c6e0e633d365dca62a9726037c5cfefcbaa2c 100644 (file)
@@ -4,16 +4,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -82,7 +82,7 @@ static void jfs_handle_error(struct super_block *sb)
                        "as read-only\n",
                        sb->s_id);
                sb->s_flags |= MS_RDONLY;
-       } 
+       }
 
        /* nothing is done for continue beyond marking the superblock dirty */
 }
@@ -422,7 +422,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
 
        sbi = kzalloc(sizeof (struct jfs_sb_info), GFP_KERNEL);
        if (!sbi)
-               return -ENOSPC;
+               return -ENOMEM;
        sb->s_fs_info = sbi;
        sbi->sb = sb;
        sbi->uid = sbi->gid = sbi->umask = -1;
@@ -775,7 +775,7 @@ static int __init init_jfs_fs(void)
        int rc;
 
        jfs_inode_cachep =
-           kmem_cache_create("jfs_ip", sizeof(struct jfs_inode_info), 0, 
+           kmem_cache_create("jfs_ip", sizeof(struct jfs_inode_info), 0,
                            SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD,
                            init_once, NULL);
        if (jfs_inode_cachep == NULL)
index 16477b3835e1d62235ff939bcab6f32b6be454bb..cee43f36f51d526843271398356dfb3bef030ce0 100644 (file)
@@ -3,16 +3,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
index 7a10e19289611902f88d7286b17295d69f1e0861..4c7985ebca92505ae584d43024a8bf1c4f1cc258 100644 (file)
@@ -4,16 +4,16 @@
  *
  *   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 
+ *   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 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
@@ -57,7 +57,7 @@
  *
  *   0            4                   4 + EA_SIZE(ea1)
  *   +------------+-------------------+--------------------+-----
- *   | Overall EA | First FEA Element | Second FEA Element | ..... 
+ *   | Overall EA | First FEA Element | Second FEA Element | .....
  *   | List Size  |                   |                    |
  *   +------------+-------------------+--------------------+-----
  *
@@ -155,9 +155,9 @@ static void ea_release(struct inode *inode, struct ea_buffer *ea_buf);
 
 /*
  * NAME: ea_write_inline
- *                                                                    
+ *
  * FUNCTION: Attempt to write an EA inline if area is available
- *                                                                    
+ *
  * PRE CONDITIONS:
  *     Already verified that the specified EA is small enough to fit inline
  *
@@ -216,10 +216,10 @@ static int ea_write_inline(struct inode *ip, struct jfs_ea_list *ealist,
 
 /*
  * NAME: ea_write
- *                                                                    
+ *
  * FUNCTION: Write an EA for an inode
- *                                                                    
- * PRE CONDITIONS: EA has been verified 
+ *
+ * PRE CONDITIONS: EA has been verified
  *
  * PARAMETERS:
  *     ip      - Inode pointer
@@ -340,9 +340,9 @@ static int ea_write(struct inode *ip, struct jfs_ea_list *ealist, int size,
 
 /*
  * NAME: ea_read_inline
- *                                                                    
+ *
  * FUNCTION: Read an inlined EA into user's buffer
- *                                                                    
+ *
  * PARAMETERS:
  *     ip      - Inode pointer
  *     ealist  - Pointer to buffer to fill in with EA
@@ -372,9 +372,9 @@ static int ea_read_inline(struct inode *ip, struct jfs_ea_list *ealist)
 
 /*
  * NAME: ea_read
- *                                                                    
+ *
  * FUNCTION: copy EA data into user's buffer
- *                                                                    
+ *
  * PARAMETERS:
  *     ip      - Inode pointer
  *     ealist  - Pointer to buffer to fill in with EA
@@ -406,7 +406,7 @@ static int ea_read(struct inode *ip, struct jfs_ea_list *ealist)
                return -EIO;
        }
 
-       /* 
+       /*
         * Figure out how many blocks were allocated when this EA list was
         * originally written to disk.
         */
@@ -443,14 +443,14 @@ static int ea_read(struct inode *ip, struct jfs_ea_list *ealist)
 
 /*
  * NAME: ea_get
- *                                                                    
+ *
  * FUNCTION: Returns buffer containing existing extended attributes.
  *          The size of the buffer will be the larger of the existing
  *          attributes size, or min_size.
  *
  *          The buffer, which may be inlined in the inode or in the
- *          page cache must be release by calling ea_release or ea_put
- *                                                                    
+ *          page cache must be release by calling ea_release or ea_put
+ *
  * PARAMETERS:
  *     inode   - Inode pointer
  *     ea_buf  - Structure to be populated with ealist and its metadata
@@ -1054,7 +1054,7 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size)
 
        /* compute required size of list */
        for (ea = FIRST_EA(ealist); ea < END_EALIST(ealist); ea = NEXT_EA(ea)) {
-               if (can_list(ea))
+               if (can_list(ea))
                        size += name_size(ea) + 1;
        }
 
@@ -1069,7 +1069,7 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size)
        /* Copy attribute names to buffer */
        buffer = data;
        for (ea = FIRST_EA(ealist); ea < END_EALIST(ealist); ea = NEXT_EA(ea)) {
-               if (can_list(ea)) {
+               if (can_list(ea)) {
                        int namelen = copy_name(buffer, ea);
                        buffer += namelen + 1;
                }
index f95cc3f3c42db4ff709cd2a4f203d78a619323b6..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();
+       lockd_up(0); /* note: this cannot fail as lockd is already running */
+
+       dprintk("lockd: reclaiming locks for host %s", host->h_name);
 
-       nlmclnt_prepare_reclaim(host);
-       /* First, reclaim all locks that have been marked. */
 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 271e2165fff6ebf8577f4f5ab590a911ec9bedfe..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)
@@ -129,11 +129,11 @@ static void nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl)
        nlmclnt_next_cookie(&argp->cookie);
        argp->state   = nsm_local_state;
        memcpy(&lock->fh, NFS_FH(fl->fl_file->f_dentry->d_inode), sizeof(struct nfs_fh));
-       lock->caller  = system_utsname.nodename;
+       lock->caller  = utsname()->nodename;
        lock->oh.data = req->a_owner;
        lock->oh.len  = snprintf(req->a_owner, sizeof(req->a_owner), "%u@%s",
                                (unsigned int)fl->fl_u.nfs_fl.owner->pid,
-                               system_utsname.nodename);
+                               utsname()->nodename);
        lock->svid = fl->fl_u.nfs_fl.owner->pid;
        lock->fl.fl_start = fl->fl_start;
        lock->fl.fl_end = fl->fl_end;
@@ -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 5954dcb497e4e43b241ba48d6cab7f6b1453e307..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,9 +159,14 @@ 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))
-        || !(p = xdr_encode_string(p, system_utsname.nodename)))
+       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);
        *p++ = htonl(argp->vers);
@@ -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 9a991b52c647d7614cb014100c73b1124751b517..634139232aafae89c3e14b9ceaf7fa8ee13e5bd2 100644 (file)
@@ -31,7 +31,9 @@
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/svc.h>
 #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
@@ -46,6 +48,7 @@ EXPORT_SYMBOL(nlmsvc_ops);
 static DEFINE_MUTEX(nlmsvc_mutex);
 static unsigned int            nlmsvc_users;
 static pid_t                   nlmsvc_pid;
+static struct svc_serv         *nlmsvc_serv;
 int                            nlmsvc_grace_period;
 unsigned long                  nlmsvc_timeout;
 
@@ -59,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.
@@ -96,7 +100,6 @@ static inline void clear_grace_period(void)
 static void
 lockd(struct svc_rqst *rqstp)
 {
-       struct svc_serv *serv = rqstp->rq_server;
        int             err = 0;
        unsigned long grace_period_expire;
 
@@ -112,6 +115,7 @@ lockd(struct svc_rqst *rqstp)
         * Let our maker know we're running.
         */
        nlmsvc_pid = current->pid;
+       nlmsvc_serv = rqstp->rq_server;
        complete(&lockd_start_done);
 
        daemonize("lockd");
@@ -161,7 +165,7 @@ lockd(struct svc_rqst *rqstp)
                 * Find a socket with data available and call its
                 * recvfrom routine.
                 */
-               err = svc_recv(serv, rqstp, timeout);
+               err = svc_recv(rqstp, timeout);
                if (err == -EAGAIN || err == -EINTR)
                        continue;
                if (err < 0) {
@@ -174,7 +178,7 @@ lockd(struct svc_rqst *rqstp)
                dprintk("lockd: request from %08x\n",
                        (unsigned)ntohl(rqstp->rq_addr.sin_addr.s_addr));
 
-               svc_process(serv, rqstp);
+               svc_process(rqstp);
 
        }
 
@@ -189,6 +193,7 @@ lockd(struct svc_rqst *rqstp)
                        nlmsvc_invalidate_all();
                nlm_shutdown_hosts();
                nlmsvc_pid = 0;
+               nlmsvc_serv = NULL;
        } else
                printk(KERN_DEBUG
                        "lockd: new process, skipping host shutdown\n");
@@ -205,54 +210,77 @@ lockd(struct svc_rqst *rqstp)
        module_put_and_exit(0);
 }
 
+
+static int find_socket(struct svc_serv *serv, int proto)
+{
+       struct svc_sock *svsk;
+       int found = 0;
+       list_for_each_entry(svsk, &serv->sv_permsocks, sk_list)
+               if (svsk->sk_sk->sk_protocol == proto) {
+                       found = 1;
+                       break;
+               }
+       return found;
+}
+
+static int make_socks(struct svc_serv *serv, int proto)
+{
+       /* Make any sockets that are needed but not present.
+        * If nlm_udpport or nlm_tcpport were set as module
+        * options, make those sockets unconditionally
+        */
+       static int              warned;
+       int err = 0;
+       if (proto == IPPROTO_UDP || nlm_udpport)
+               if (!find_socket(serv, IPPROTO_UDP))
+                       err = svc_makesock(serv, IPPROTO_UDP, nlm_udpport);
+       if (err == 0 && (proto == IPPROTO_TCP || nlm_tcpport))
+               if (!find_socket(serv, IPPROTO_TCP))
+                       err= svc_makesock(serv, IPPROTO_TCP, nlm_tcpport);
+       if (!err)
+               warned = 0;
+       else if (warned++ == 0)
+               printk(KERN_WARNING
+                      "lockd_up: makesock failed, error=%d\n", err);
+       return err;
+}
+
 /*
  * Bring up the lockd process if it's not already up.
  */
 int
-lockd_up(void)
+lockd_up(int proto) /* Maybe add a 'family' option when IPv6 is supported ?? */
 {
-       static int              warned;
        struct svc_serv *       serv;
        int                     error = 0;
 
        mutex_lock(&nlmsvc_mutex);
-       /*
-        * Unconditionally increment the user count ... this is
-        * the number of clients who _want_ a lockd process.
-        */
-       nlmsvc_users++; 
        /*
         * Check whether we're already up and running.
         */
-       if (nlmsvc_pid)
+       if (nlmsvc_pid) {
+               if (proto)
+                       error = make_socks(nlmsvc_serv, proto);
                goto out;
+       }
 
        /*
         * Sanity check: if there's no pid,
         * we should be the first user ...
         */
-       if (nlmsvc_users > 1)
+       if (nlmsvc_users)
                printk(KERN_WARNING
                        "lockd_up: no pid, %d users??\n", nlmsvc_users);
 
        error = -ENOMEM;
-       serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE);
+       serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL);
        if (!serv) {
                printk(KERN_WARNING "lockd_up: create service failed\n");
                goto out;
        }
 
-       if ((error = svc_makesock(serv, IPPROTO_UDP, nlm_udpport)) < 0 
-#ifdef CONFIG_NFSD_TCP
-        || (error = svc_makesock(serv, IPPROTO_TCP, nlm_tcpport)) < 0
-#endif
-               ) {
-               if (warned++ == 0) 
-                       printk(KERN_WARNING
-                               "lockd_up: makesock failed, error=%d\n", error);
+       if ((error = make_socks(serv, proto)) < 0)
                goto destroy_and_out;
-       } 
-       warned = 0;
 
        /*
         * Create the kernel thread and wait for it to start.
@@ -272,6 +300,8 @@ lockd_up(void)
 destroy_and_out:
        svc_destroy(serv);
 out:
+       if (!error)
+               nlmsvc_users++;
        mutex_unlock(&nlmsvc_mutex);
        return error;
 }
@@ -367,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 }
 };
 
@@ -455,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 c9d419703cf30b35daa6fcf17609b948f465b4a0..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);
 }
 
 /*
@@ -325,7 +306,7 @@ static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock)
 {
        locks_copy_lock(&call->a_args.lock.fl, &lock->fl);
        memcpy(&call->a_args.lock.fh, &lock->fh, sizeof(call->a_args.lock.fh));
-       call->a_args.lock.caller = system_utsname.nodename;
+       call->a_args.lock.caller = utsname()->nodename;
        call->a_args.lock.oh.len = lock->oh.len;
 
        /* set default data area */
@@ -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 033ea4ac2c30be2590f36103d9f2f1fe4dd7023a..61c46facf257413f21ca462a9466e402265df906 100644 (file)
@@ -515,7 +515,7 @@ nlmclt_decode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp)
  */
 #define NLM_void_sz            0
 #define NLM_cookie_sz          1+XDR_QUADLEN(NLM_MAXCOOKIELEN)
-#define NLM_caller_sz          1+XDR_QUADLEN(sizeof(system_utsname.nodename))
+#define NLM_caller_sz          1+XDR_QUADLEN(sizeof(utsname()->nodename))
 #define NLM_netobj_sz          1+XDR_QUADLEN(XDR_MAX_NETOBJ)
 /* #define NLM_owner_sz                1+XDR_QUADLEN(NLM_MAXOWNER) */
 #define NLM_fhandle_sz         1+XDR_QUADLEN(NFS2_FHSIZE)
index 21dfadfca2bc1402613407215a807ee3bda44173..e0b6a80649a01ff79c26206c039ece3d4faebd0c 100644 (file)
@@ -1514,7 +1514,7 @@ int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
                goto out_unlock;
        }
 
-       error = f_setown(filp, current->pid, 0);
+       error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0);
 out_unlock:
        unlock_kernel();
        return error;
index 66d921e14feebaa532bed7e6a041ba08e5057a8c..55442a6cf22133d2c9687636b3e3ca788eacac53 100644 (file)
@@ -133,7 +133,7 @@ struct vfsmount *lookup_mnt(struct vfsmount *mnt, struct dentry *dentry)
 
 static inline int check_mnt(struct vfsmount *mnt)
 {
-       return mnt->mnt_namespace == current->namespace;
+       return mnt->mnt_namespace == current->nsproxy->namespace;
 }
 
 static void touch_namespace(struct namespace *ns)
@@ -830,7 +830,7 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt,
        if (parent_nd) {
                detach_mnt(source_mnt, parent_nd);
                attach_mnt(source_mnt, nd);
-               touch_namespace(current->namespace);
+               touch_namespace(current->nsproxy->namespace);
        } else {
                mnt_set_mountpoint(dest_mnt, dest_dentry, source_mnt);
                commit_tree(source_mnt);
@@ -1441,7 +1441,7 @@ dput_out:
  */
 struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs)
 {
-       struct namespace *namespace = tsk->namespace;
+       struct namespace *namespace = tsk->nsproxy->namespace;
        struct namespace *new_ns;
        struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL;
        struct vfsmount *p, *q;
@@ -1508,7 +1508,7 @@ struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs)
 
 int copy_namespace(int flags, struct task_struct *tsk)
 {
-       struct namespace *namespace = tsk->namespace;
+       struct namespace *namespace = tsk->nsproxy->namespace;
        struct namespace *new_ns;
        int err = 0;
 
@@ -1531,7 +1531,7 @@ int copy_namespace(int flags, struct task_struct *tsk)
                goto out;
        }
 
-       tsk->namespace = new_ns;
+       tsk->nsproxy->namespace = new_ns;
 
 out:
        put_namespace(namespace);
@@ -1754,7 +1754,7 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
        detach_mnt(user_nd.mnt, &root_parent);
        attach_mnt(user_nd.mnt, &old_nd);     /* mount old root on put_old */
        attach_mnt(new_nd.mnt, &root_parent); /* mount new_root on / */
-       touch_namespace(current->namespace);
+       touch_namespace(current->nsproxy->namespace);
        spin_unlock(&vfsmount_lock);
        chroot_fs_refs(&user_nd, &new_nd);
        security_sb_post_pivotroot(&user_nd, &new_nd);
@@ -1780,7 +1780,6 @@ static void __init init_mount_tree(void)
 {
        struct vfsmount *mnt;
        struct namespace *namespace;
-       struct task_struct *g, *p;
 
        mnt = do_kern_mount("rootfs", 0, "rootfs", NULL);
        if (IS_ERR(mnt))
@@ -1796,13 +1795,8 @@ static void __init init_mount_tree(void)
        namespace->root = mnt;
        mnt->mnt_namespace = namespace;
 
-       init_task.namespace = namespace;
-       read_lock(&tasklist_lock);
-       do_each_thread(g, p) {
-               get_namespace(namespace);
-               p->namespace = namespace;
-       } while_each_thread(g, p);
-       read_unlock(&tasklist_lock);
+       init_task.nsproxy->namespace = namespace;
+       get_namespace(namespace);
 
        set_fs_pwd(current->fs, namespace->root, namespace->root->mnt_root);
        set_fs_root(current->fs, namespace->root, namespace->root->mnt_root);
index a3ee11364db02044e07cd6dce7a5546aa4016650..7933e2e99dbc2a4d448591aa87d17f937d816619 100644 (file)
@@ -58,7 +58,6 @@ module_param_call(callback_tcpport, param_set_port, param_get_int,
  */
 static void nfs_callback_svc(struct svc_rqst *rqstp)
 {
-       struct svc_serv *serv = rqstp->rq_server;
        int err;
 
        __module_get(THIS_MODULE);
@@ -80,7 +79,7 @@ static void nfs_callback_svc(struct svc_rqst *rqstp)
                /*
                 * Listen for a request on the socket
                 */
-               err = svc_recv(serv, rqstp, MAX_SCHEDULE_TIMEOUT);
+               err = svc_recv(rqstp, MAX_SCHEDULE_TIMEOUT);
                if (err == -EAGAIN || err == -EINTR)
                        continue;
                if (err < 0) {
@@ -91,7 +90,7 @@ static void nfs_callback_svc(struct svc_rqst *rqstp)
                }
                dprintk("%s: request from %u.%u.%u.%u\n", __FUNCTION__,
                                NIPQUAD(rqstp->rq_addr.sin_addr.s_addr));
-               svc_process(serv, rqstp);
+               svc_process(rqstp);
        }
 
        svc_exit_thread(rqstp);
@@ -116,7 +115,7 @@ int nfs_callback_up(void)
                goto out;
        init_completion(&nfs_callback_info.started);
        init_completion(&nfs_callback_info.stopped);
-       serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE);
+       serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, NULL);
        ret = -ENOMEM;
        if (!serv)
                goto out_err;
index ec1938d4b814f3d3b9e031aa076499c7ca6102bd..8106f3b29e4aa9747fd786280b132d7c41332154 100644 (file)
@@ -460,7 +460,8 @@ static int nfs_start_lockd(struct nfs_server *server)
                goto out;
        if (server->flags & NFS_MOUNT_NONLM)
                goto out;
-       error = lockd_up();
+       error = lockd_up((server->flags & NFS_MOUNT_TCP) ?
+                       IPPROTO_TCP : IPPROTO_UDP);
        if (error < 0)
                server->flags |= NFS_MOUNT_NONLM;
        else
index c0a754ecdee66447464a9bb67c900071896909a3..1d656a64519977189d7741e944dd11832e6e51ae 100644 (file)
@@ -312,7 +312,7 @@ static int __init root_nfs_name(char *name)
        /* Override them by options set on kernel command-line */
        root_nfs_parse(name, buf);
 
-       cp = system_utsname.nodename;
+       cp = utsname()->nodename;
        if (strlen(buf) + strlen(cp) > NFS_MAXPATHLEN) {
                printk(KERN_ERR "Root-NFS: Pathname for remote directory too long.\n");
                return -1;
index 01bc68c628ad16b92f84ce183e9cf908e09511c3..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);
 }
 
@@ -370,7 +383,7 @@ static int check_export(struct inode *inode, int flags)
         */
        if (!(inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV) &&
            !(flags & NFSEXP_FSID)) {
-               dprintk("exp_export: export of non-dev fs without fsid");
+               dprintk("exp_export: export of non-dev fs without fsid\n");
                return -EINVAL;
        }
        if (!inode->i_sb->s_export_op) {
@@ -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,36 +1152,28 @@ 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;
 }
 
 /* Iterator */
 
 static void *e_start(struct seq_file *m, loff_t *pos)
+       __acquires(svc_export_cache.hash_lock)
 {
        loff_t n = *pos;
        unsigned hash, export;
@@ -1086,7 +1182,7 @@ static void *e_start(struct seq_file *m, loff_t *pos)
        exp_readlock();
        read_lock(&svc_export_cache.hash_lock);
        if (!n--)
-               return (void *)1;
+               return SEQ_START_TOKEN;
        hash = n >> 32;
        export = n & ((1LL<<32) - 1);
 
@@ -1110,7 +1206,7 @@ static void *e_next(struct seq_file *m, void *p, loff_t *pos)
        struct cache_head *ch = p;
        int hash = (*pos >> 32);
 
-       if (p == (void *)1)
+       if (p == SEQ_START_TOKEN)
                hash = 0;
        else if (ch->next == NULL) {
                hash++;
@@ -1131,6 +1227,7 @@ static void *e_next(struct seq_file *m, void *p, loff_t *pos)
 }
 
 static void e_stop(struct seq_file *m, void *p)
+       __releases(svc_export_cache.hash_lock)
 {
        read_unlock(&svc_export_cache.hash_lock);
        exp_readunlock();
@@ -1156,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;
@@ -1172,21 +1270,34 @@ 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)
 {
        struct cache_head *cp = p;
        struct svc_export *exp = container_of(cp, struct svc_export, h);
-       svc_client *clp;
 
-       if (p == (void *)1) {
+       if (p == SEQ_START_TOKEN) {
                seq_puts(m, "# Version 1.1\n");
                seq_puts(m, "# Path Client(Flags) # IPs\n");
                return 0;
        }
 
-       clp = exp->ex_client;
        cache_get(&exp->h);
        if (cache_check(&svc_export_cache, &exp->h, NULL))
                return 0;
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 8583d99ee7407a894def12584afde6a5c5f9a992..f6ca9fb3fc63fb7b78870bd387d8844c648e5b57 100644 (file)
@@ -131,7 +131,7 @@ xdr_error:                                      \
 #define READ_BUF(nbytes)  do { \
        p = xdr_inline_decode(xdr, nbytes); \
        if (!p) { \
-               dprintk("NFSD: %s: reply buffer overflowed in line %d.", \
+               dprintk("NFSD: %s: reply buffer overflowed in line %d.\n", \
                        __FUNCTION__, __LINE__); \
                return -EIO; \
        } \
index ee4eff27aedc80d9faac58a7dc208929551d36ef..8333db12caca56207a0142fcb9a94000f962ad69 100644 (file)
@@ -600,7 +600,7 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_se
                        &setattr->sa_stateid, CHECK_FH | WR_STATE, NULL);
                nfs4_unlock_state();
                if (status) {
-                       dprintk("NFSD: nfsd4_setattr: couldn't process stateid!");
+                       dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n");
                        return status;
                }
        }
@@ -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 e35d7e52fdebd4f37f477fa15c8de69b821d54a4..1cbd2e4ee12252bb30c8a5c37a5aa50486584252 100644 (file)
@@ -184,7 +184,7 @@ struct dentry_list_arg {
 
 static int
 nfsd4_build_dentrylist(void *arg, const char *name, int namlen,
-               loff_t offset, ino_t ino, unsigned int d_type)
+               loff_t offset, u64 ino, unsigned int d_type)
 {
        struct dentry_list_arg *dla = arg;
        struct list_head *dentries = &dla->dentries;
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 7046ac9cf97fa14e50743ed1cc4655d4b4ec26f7..39aed901514b0c34d30cb468b1a8aabadc33b2e8 100644 (file)
 #include <linux/pagemap.h>
 #include <linux/init.h>
 #include <linux/string.h>
+#include <linux/smp_lock.h>
+#include <linux/ctype.h>
 
 #include <linux/nfs.h>
 #include <linux/nfsd_idmap.h>
+#include <linux/lockd/bind.h>
 #include <linux/sunrpc/svc.h>
+#include <linux/sunrpc/svcsock.h>
 #include <linux/nfsd/nfsd.h>
 #include <linux/nfsd/cache.h>
 #include <linux/nfsd/xdr.h>
@@ -35,8 +39,6 @@
 
 #include <asm/uaccess.h>
 
-unsigned int nfsd_versbits = ~0;
-
 /*
  *     We have a single directory with 9 nodes in it.
  */
@@ -52,7 +54,10 @@ enum {
        NFSD_List,
        NFSD_Fh,
        NFSD_Threads,
+       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
@@ -75,7 +80,10 @@ static ssize_t write_getfd(struct file *file, char *buf, size_t size);
 static ssize_t write_getfs(struct file *file, char *buf, size_t size);
 static ssize_t write_filehandle(struct file *file, char *buf, size_t size);
 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);
@@ -91,7 +99,10 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = {
        [NFSD_Getfs] = write_getfs,
        [NFSD_Fh] = write_filehandle,
        [NFSD_Threads] = write_threads,
+       [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,
@@ -358,6 +369,72 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size)
        return strlen(buf);
 }
 
+extern int nfsd_nrpools(void);
+extern int nfsd_get_nrthreads(int n, int *);
+extern int nfsd_set_nrthreads(int n, int *);
+
+static ssize_t write_pool_threads(struct file *file, char *buf, size_t size)
+{
+       /* if size > 0, look for an array of number of threads per node
+        * and apply them  then write out number of threads per node as reply
+        */
+       char *mesg = buf;
+       int i;
+       int rv;
+       int len;
+       int npools = nfsd_nrpools();
+       int *nthreads;
+
+       if (npools == 0) {
+               /*
+                * NFS is shut down.  The admin can start it by
+                * writing to the threads file but NOT the pool_threads
+                * file, sorry.  Report zero threads.
+                */
+               strcpy(buf, "0\n");
+               return strlen(buf);
+       }
+
+       nthreads = kcalloc(npools, sizeof(int), GFP_KERNEL);
+       if (nthreads == NULL)
+               return -ENOMEM;
+
+       if (size > 0) {
+               for (i = 0; i < npools; i++) {
+                       rv = get_int(&mesg, &nthreads[i]);
+                       if (rv == -ENOENT)
+                               break;          /* fewer numbers than pools */
+                       if (rv)
+                               goto out_free;  /* syntax error */
+                       rv = -EINVAL;
+                       if (nthreads[i] < 0)
+                               goto out_free;
+               }
+               rv = nfsd_set_nrthreads(i, nthreads);
+               if (rv)
+                       goto out_free;
+       }
+
+       rv = nfsd_get_nrthreads(npools, nthreads);
+       if (rv)
+               goto out_free;
+
+       mesg = buf;
+       size = SIMPLE_TRANSACTION_LIMIT;
+       for (i = 0; i < npools && size > 0; i++) {
+               snprintf(mesg, size, "%d%c", nthreads[i], (i == npools-1 ? '\n' : ' '));
+               len = strlen(mesg);
+               size -= len;
+               mesg += len;
+       }
+
+       return (mesg-buf);
+
+out_free:
+       kfree(nthreads);
+       return rv;
+}
+
 static ssize_t write_versions(struct file *file, char *buf, size_t size)
 {
        /*
@@ -372,6 +449,10 @@ static ssize_t write_versions(struct file *file, char *buf, size_t size)
 
        if (size>0) {
                if (nfsd_serv)
+                       /* Cannot change versions without updating
+                        * nfsd_serv->sv_xdrsize, and reallocing
+                        * rq_argp and rq_resp
+                        */
                        return -EBUSY;
                if (buf[size-1] != '\n')
                        return -EINVAL;
@@ -390,10 +471,7 @@ static ssize_t write_versions(struct file *file, char *buf, size_t size)
                        case 2:
                        case 3:
                        case 4:
-                               if (sign != '-')
-                                       NFSCTL_VERSET(nfsd_versbits, num);
-                               else
-                                       NFSCTL_VERUNSET(nfsd_versbits, num);
+                               nfsd_vers(num, sign == '-' ? NFSD_CLEAR : NFSD_SET);
                                break;
                        default:
                                return -EINVAL;
@@ -404,16 +482,15 @@ static ssize_t write_versions(struct file *file, char *buf, size_t size)
                /* If all get turned off, turn them back on, as
                 * having no versions is BAD
                 */
-               if ((nfsd_versbits & NFSCTL_VERALL)==0)
-                       nfsd_versbits = NFSCTL_VERALL;
+               nfsd_reset_versions();
        }
        /* Now write current state into reply buffer */
        len = 0;
        sep = "";
        for (num=2 ; num <= 4 ; num++)
-               if (NFSCTL_VERISSET(NFSCTL_VERALL, num)) {
+               if (nfsd_vers(num, NFSD_AVAIL)) {
                        len += sprintf(buf+len, "%s%c%d", sep,
-                                      NFSCTL_VERISSET(nfsd_versbits, num)?'+':'-',
+                                      nfsd_vers(num, NFSD_TEST)?'+':'-',
                                       num);
                        sep = " ";
                }
@@ -421,6 +498,95 @@ static ssize_t write_versions(struct file *file, char *buf, size_t size)
        return len;
 }
 
+static ssize_t write_ports(struct file *file, char *buf, size_t size)
+{
+       if (size == 0) {
+               int len = 0;
+               lock_kernel();
+               if (nfsd_serv)
+                       len = svc_sock_names(buf, nfsd_serv, NULL);
+               unlock_kernel();
+               return len;
+       }
+       /* Either a single 'fd' number is written, in which
+        * case it must be for a socket of a supported family/protocol,
+        * and we use it as an nfsd socket, or
+        * A '-' followed by the 'name' of a socket in which case
+        * we close the socket.
+        */
+       if (isdigit(buf[0])) {
+               char *mesg = buf;
+               int fd;
+               int err;
+               err = get_int(&mesg, &fd);
+               if (err)
+                       return -EINVAL;
+               if (fd < 0)
+                       return -EINVAL;
+               err = nfsd_create_serv();
+               if (!err) {
+                       int proto = 0;
+                       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 < 0 ? err : 0;
+       }
+       if (buf[0] == '-') {
+               char *toclose = kstrdup(buf+1, GFP_KERNEL);
+               int len = 0;
+               if (!toclose)
+                       return -ENOMEM;
+               lock_kernel();
+               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);
 
@@ -483,7 +649,10 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
                [NFSD_List] = {"exports", &exports_operations, S_IRUGO},
                [NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR},
                [NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
+               [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 ec1decf29babd194b8ea8f2ae94912f252d770ec..6fa6340a5fb892e217e180218d3199bc4e4b3e55 100644 (file)
@@ -57,12 +57,6 @@ static atomic_t                      nfsd_busy;
 static unsigned long           nfsd_last_call;
 static DEFINE_SPINLOCK(nfsd_call_lock);
 
-struct nfsd_list {
-       struct list_head        list;
-       struct task_struct      *task;
-};
-static struct list_head nfsd_list = LIST_HEAD_INIT(nfsd_list);
-
 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
 static struct svc_stat nfsd_acl_svcstats;
 static struct svc_version *    nfsd_acl_version[] = {
@@ -117,6 +111,32 @@ struct svc_program         nfsd_program = {
 
 };
 
+int nfsd_vers(int vers, enum vers_op change)
+{
+       if (vers < NFSD_MINVERS || vers >= NFSD_NRVERS)
+               return -1;
+       switch(change) {
+       case NFSD_SET:
+               nfsd_versions[vers] = nfsd_version[vers];
+               break;
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+               if (vers < NFSD_ACL_NRVERS)
+                       nfsd_acl_version[vers] = nfsd_acl_version[vers];
+#endif
+       case NFSD_CLEAR:
+               nfsd_versions[vers] = NULL;
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+               if (vers < NFSD_ACL_NRVERS)
+                       nfsd_acl_version[vers] = NULL;
+#endif
+               break;
+       case NFSD_TEST:
+               return nfsd_versions[vers] != NULL;
+       case NFSD_AVAIL:
+               return nfsd_version[vers] != NULL;
+       }
+       return 0;
+}
 /*
  * Maximum number of nfsd processes
  */
@@ -130,16 +150,192 @@ int nfsd_nrthreads(void)
                return nfsd_serv->sv_nrthreads;
 }
 
+static int killsig;    /* signal that was used to kill last nfsd */
+static void nfsd_last_thread(struct svc_serv *serv)
+{
+       /* When last nfsd thread exits we need to do some clean-up */
+       struct svc_sock *svsk;
+       list_for_each_entry(svsk, &serv->sv_permsocks, sk_list)
+               lockd_down();
+       nfsd_serv = NULL;
+       nfsd_racache_shutdown();
+       nfs4_state_shutdown();
+
+       printk(KERN_WARNING "nfsd: last server has exited\n");
+       if (killsig != SIG_NOCLEAN) {
+               printk(KERN_WARNING "nfsd: unexporting all filesystems\n");
+               nfsd_export_flush();
+       }
+}
+
+void nfsd_reset_versions(void)
+{
+       int found_one = 0;
+       int i;
+
+       for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
+               if (nfsd_program.pg_vers[i])
+                       found_one = 1;
+       }
+
+       if (!found_one) {
+               for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++)
+                       nfsd_program.pg_vers[i] = nfsd_version[i];
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+               for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++)
+                       nfsd_acl_program.pg_vers[i] =
+                               nfsd_acl_version[i];
+#endif
+       }
+}
+
+int nfsd_create_serv(void)
+{
+       int err = 0;
+       lock_kernel();
+       if (nfsd_serv) {
+               svc_get(nfsd_serv);
+               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 - NFSSVC_MAXBLKSIZE + nfsd_max_blksize,
+                                     nfsd_last_thread,
+                                     nfsd, SIG_NOCLEAN, THIS_MODULE);
+       if (nfsd_serv == NULL)
+               err = -ENOMEM;
+       unlock_kernel();
+       do_gettimeofday(&nfssvc_boot);          /* record boot time */
+       return err;
+}
+
+static int nfsd_init_socks(int port)
+{
+       int error;
+       if (!list_empty(&nfsd_serv->sv_permsocks))
+               return 0;
+
+       error = lockd_up(IPPROTO_UDP);
+       if (error >= 0) {
+               error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
+               if (error < 0)
+                       lockd_down();
+       }
+       if (error < 0)
+               return error;
+
+#ifdef CONFIG_NFSD_TCP
+       error = lockd_up(IPPROTO_TCP);
+       if (error >= 0) {
+               error = svc_makesock(nfsd_serv, IPPROTO_TCP, port);
+               if (error < 0)
+                       lockd_down();
+       }
+       if (error < 0)
+               return error;
+#endif
+       return 0;
+}
+
+int nfsd_nrpools(void)
+{
+       if (nfsd_serv == NULL)
+               return 0;
+       else
+               return nfsd_serv->sv_nrpools;
+}
+
+int nfsd_get_nrthreads(int n, int *nthreads)
+{
+       int i = 0;
+
+       if (nfsd_serv != NULL) {
+               for (i = 0; i < nfsd_serv->sv_nrpools && i < n; i++)
+                       nthreads[i] = nfsd_serv->sv_pools[i].sp_nrthreads;
+       }
+
+       return 0;
+}
+
+int nfsd_set_nrthreads(int n, int *nthreads)
+{
+       int i = 0;
+       int tot = 0;
+       int err = 0;
+
+       if (nfsd_serv == NULL || n <= 0)
+               return 0;
+
+       if (n > nfsd_serv->sv_nrpools)
+               n = nfsd_serv->sv_nrpools;
+
+       /* enforce a global maximum number of threads */
+       tot = 0;
+       for (i = 0; i < n; i++) {
+               if (nthreads[i] > NFSD_MAXSERVS)
+                       nthreads[i] = NFSD_MAXSERVS;
+               tot += nthreads[i];
+       }
+       if (tot > NFSD_MAXSERVS) {
+               /* total too large: scale down requested numbers */
+               for (i = 0; i < n && tot > 0; i++) {
+                       int new = nthreads[i] * NFSD_MAXSERVS / tot;
+                       tot -= (nthreads[i] - new);
+                       nthreads[i] = new;
+               }
+               for (i = 0; i < n && tot > 0; i++) {
+                       nthreads[i]--;
+                       tot--;
+               }
+       }
+
+       /*
+        * There must always be a thread in pool 0; the admin
+        * can't shut down NFS completely using pool_threads.
+        */
+       if (nthreads[0] == 0)
+               nthreads[0] = 1;
+
+       /* apply the new numbers */
+       lock_kernel();
+       svc_get(nfsd_serv);
+       for (i = 0; i < n; i++) {
+               err = svc_set_num_threads(nfsd_serv, &nfsd_serv->sv_pools[i],
+                                         nthreads[i]);
+               if (err)
+                       break;
+       }
+       svc_destroy(nfsd_serv);
+       unlock_kernel();
+
+       return err;
+}
+
 int
 nfsd_svc(unsigned short port, int nrservs)
 {
        int     error;
-       int     none_left, found_one, i;
-       struct list_head *victim;
        
        lock_kernel();
-       dprintk("nfsd: creating service: vers 0x%x\n",
-               nfsd_versbits);
+       dprintk("nfsd: creating service\n");
        error = -EINVAL;
        if (nrservs <= 0)
                nrservs = 0;
@@ -153,91 +349,20 @@ nfsd_svc(unsigned short port, int nrservs)
        error = nfs4_state_start();
        if (error<0)
                goto out;
-       if (!nfsd_serv) {
-               /*
-                * Use the nfsd_ctlbits to define which
-                * versions that will be advertised.
-                * If nfsd_ctlbits doesn't list any version,
-                * export them all.
-                */
-               found_one = 0;
-
-               for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
-                       if (NFSCTL_VERISSET(nfsd_versbits, i)) {
-                               nfsd_program.pg_vers[i] = nfsd_version[i];
-                               found_one = 1;
-                       } else
-                               nfsd_program.pg_vers[i] = NULL;
-               }
 
-               if (!found_one) {
-                       for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++)
-                               nfsd_program.pg_vers[i] = nfsd_version[i];
-               }
+       nfsd_reset_versions();
 
+       error = nfsd_create_serv();
 
-#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
-               found_one = 0;
-
-               for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++) {
-                       if (NFSCTL_VERISSET(nfsd_versbits, i)) {
-                               nfsd_acl_program.pg_vers[i] =
-                                       nfsd_acl_version[i];
-                               found_one = 1;
-                       } else
-                               nfsd_acl_program.pg_vers[i] = NULL;
-               }
-
-               if (!found_one) {
-                       for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++)
-                               nfsd_acl_program.pg_vers[i] =
-                                       nfsd_acl_version[i];
-               }
-#endif
-
-               atomic_set(&nfsd_busy, 0);
-               error = -ENOMEM;
-               nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE);
-               if (nfsd_serv == NULL)
-                       goto out;
-               error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
-               if (error < 0)
-                       goto failure;
+       if (error)
+               goto out;
+       error = nfsd_init_socks(port);
+       if (error)
+               goto failure;
 
-#ifdef CONFIG_NFSD_TCP
-               error = svc_makesock(nfsd_serv, IPPROTO_TCP, port);
-               if (error < 0)
-                       goto failure;
-#endif
-               do_gettimeofday(&nfssvc_boot);          /* record boot time */
-       } else
-               nfsd_serv->sv_nrthreads++;
-       nrservs -= (nfsd_serv->sv_nrthreads-1);
-       while (nrservs > 0) {
-               nrservs--;
-               __module_get(THIS_MODULE);
-               error = svc_create_thread(nfsd, nfsd_serv);
-               if (error < 0) {
-                       module_put(THIS_MODULE);
-                       break;
-               }
-       }
-       victim = nfsd_list.next;
-       while (nrservs < 0 && victim != &nfsd_list) {
-               struct nfsd_list *nl =
-                       list_entry(victim,struct nfsd_list, list);
-               victim = victim->next;
-               send_sig(SIG_NOCLEAN, nl->task, 1);
-               nrservs++;
-       }
+       error = svc_set_num_threads(nfsd_serv, NULL, nrservs);
  failure:
-       none_left = (nfsd_serv->sv_nrthreads == 1);
        svc_destroy(nfsd_serv);         /* Release server */
-       if (none_left) {
-               nfsd_serv = NULL;
-               nfsd_racache_shutdown();
-               nfs4_state_shutdown();
-       }
  out:
        unlock_kernel();
        return error;
@@ -270,10 +395,8 @@ update_thread_usage(int busy_threads)
 static void
 nfsd(struct svc_rqst *rqstp)
 {
-       struct svc_serv *serv = rqstp->rq_server;
        struct fs_struct *fsp;
        int             err;
-       struct nfsd_list me;
        sigset_t shutdown_mask, allowed_mask;
 
        /* Lock module and set up kernel thread */
@@ -297,10 +420,7 @@ nfsd(struct svc_rqst *rqstp)
 
        nfsdstats.th_cnt++;
 
-       lockd_up();                             /* start lockd */
-
-       me.task = current;
-       list_add(&me.list, &nfsd_list);
+       rqstp->rq_task = current;
 
        unlock_kernel();
 
@@ -322,8 +442,7 @@ nfsd(struct svc_rqst *rqstp)
                 * Find a socket with data available and call its
                 * recvfrom routine.
                 */
-               while ((err = svc_recv(serv, rqstp,
-                                      60*60*HZ)) == -EAGAIN)
+               while ((err = svc_recv(rqstp, 60*60*HZ)) == -EAGAIN)
                        ;
                if (err < 0)
                        break;
@@ -336,7 +455,7 @@ nfsd(struct svc_rqst *rqstp)
                /* Process request with signals blocked.  */
                sigprocmask(SIG_SETMASK, &allowed_mask, NULL);
 
-               svc_process(serv, rqstp);
+               svc_process(rqstp);
 
                /* Unlock export hash tables */
                exp_readunlock();
@@ -353,29 +472,13 @@ nfsd(struct svc_rqst *rqstp)
                        if (sigismember(&current->pending.signal, signo) &&
                            !sigismember(&current->blocked, signo))
                                break;
-               err = signo;
+               killsig = signo;
        }
-       /* Clear signals before calling lockd_down() and svc_exit_thread() */
+       /* Clear signals before calling svc_exit_thread() */
        flush_signals(current);
 
        lock_kernel();
 
-       /* Release lockd */
-       lockd_down();
-
-       /* Check if this is last thread */
-       if (serv->sv_nrthreads==1) {
-               
-               printk(KERN_WARNING "nfsd: last server has exited\n");
-               if (err != SIG_NOCLEAN) {
-                       printk(KERN_WARNING "nfsd: unexporting all filesystems\n");
-                       nfsd_export_flush();
-               }
-               nfsd_serv = NULL;
-               nfsd_racache_shutdown();        /* release read-ahead cache */
-               nfs4_state_shutdown();
-       }
-       list_del(&me.list);
        nfsdstats.th_cnt --;
 
 out:
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 c9e3b5a8fe07d6ce8a790f668da75898cb0474f7..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) {
@@ -1114,7 +1132,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
         */
        if (!resfhp->fh_dentry) {
                /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */
-               fh_lock(fhp);
+               fh_lock_nested(fhp, I_MUTEX_PARENT);
                dchild = lookup_one_len(fname, dentry, flen);
                err = PTR_ERR(dchild);
                if (IS_ERR(dchild))
@@ -1240,7 +1258,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
        err = nfserr_notdir;
        if(!dirp->i_op || !dirp->i_op->lookup)
                goto out;
-       fh_lock(fhp);
+       fh_lock_nested(fhp, I_MUTEX_PARENT);
 
        /*
         * Compose the response file handle.
@@ -1494,7 +1512,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
        if (isdotent(name, len))
                goto out;
 
-       fh_lock(ffhp);
+       fh_lock_nested(ffhp, I_MUTEX_PARENT);
        ddir = ffhp->fh_dentry;
        dirp = ddir->d_inode;
 
@@ -1644,7 +1662,7 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
        if (err)
                goto out;
 
-       fh_lock(fhp);
+       fh_lock_nested(fhp, I_MUTEX_PARENT);
        dentry = fhp->fh_dentry;
        dirp = dentry->d_inode;
 
@@ -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 9de6b495f1128c09dd7c7d87767473e0431122cd..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
@@ -163,8 +163,6 @@ int register_nls(struct nls_table * nls)
 {
        struct nls_table ** tmp = &tables;
 
-       if (!nls)
-               return -EINVAL;
        if (nls->next)
                return -EBUSY;
 
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 c0e554971df01dbac80e057bde18b94e6648faa9..25e917fb47399bf22761fb8ed47b190776ee6cff 100644 (file)
@@ -162,7 +162,7 @@ static inline char * task_state(struct task_struct *p, char *buffer)
        int g;
        struct fdtable *fdt = NULL;
 
-       read_lock(&tasklist_lock);
+       rcu_read_lock();
        buffer += sprintf(buffer,
                "State:\t%s\n"
                "SleepAVG:\t%lu%%\n"
@@ -174,14 +174,13 @@ static inline char * task_state(struct task_struct *p, char *buffer)
                "Gid:\t%d\t%d\t%d\t%d\n",
                get_task_state(p),
                (p->sleep_avg/1024)*100/(1020000000/1024),
-               p->tgid,
-               p->pid, pid_alive(p) ? p->group_leader->real_parent->tgid : 0,
-               pid_alive(p) && p->ptrace ? p->parent->pid : 0,
+               p->tgid, p->pid,
+               pid_alive(p) ? rcu_dereference(p->real_parent)->tgid : 0,
+               pid_alive(p) && p->ptrace ? rcu_dereference(p->parent)->pid : 0,
                p->uid, p->euid, p->suid, p->fsuid,
                p->gid, p->egid, p->sgid, p->fsgid);
-       read_unlock(&tasklist_lock);
+
        task_lock(p);
-       rcu_read_lock();
        if (p->files)
                fdt = files_fdtable(p->files);
        buffer += sprintf(buffer,
@@ -244,6 +243,7 @@ static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign,
 
 static inline char * task_sig(struct task_struct *p, char *buffer)
 {
+       unsigned long flags;
        sigset_t pending, shpending, blocked, ignored, caught;
        int num_threads = 0;
        unsigned long qsize = 0;
@@ -255,10 +255,8 @@ static inline char * task_sig(struct task_struct *p, char *buffer)
        sigemptyset(&ignored);
        sigemptyset(&caught);
 
-       /* Gather all the data with the appropriate locks held */
-       read_lock(&tasklist_lock);
-       if (p->sighand) {
-               spin_lock_irq(&p->sighand->siglock);
+       rcu_read_lock();
+       if (lock_task_sighand(p, &flags)) {
                pending = p->pending.signal;
                shpending = p->signal->shared_pending.signal;
                blocked = p->blocked;
@@ -266,9 +264,9 @@ static inline char * task_sig(struct task_struct *p, char *buffer)
                num_threads = atomic_read(&p->signal->count);
                qsize = atomic_read(&p->user->sigpending);
                qlim = p->signal->rlim[RLIMIT_SIGPENDING].rlim_cur;
-               spin_unlock_irq(&p->sighand->siglock);
+               unlock_task_sighand(p, &flags);
        }
-       read_unlock(&tasklist_lock);
+       rcu_read_unlock();
 
        buffer += sprintf(buffer, "Threads:\t%d\n", num_threads);
        buffer += sprintf(buffer, "SigQ:\t%lu/%lu\n", qsize, qlim);
@@ -322,7 +320,7 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
        sigset_t sigign, sigcatch;
        char state;
        int res;
-       pid_t ppid, pgid = -1, sid = -1;
+       pid_t ppid = 0, pgid = -1, sid = -1;
        int num_threads = 0;
        struct mm_struct *mm;
        unsigned long long start_time;
@@ -330,8 +328,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
        unsigned long  min_flt = 0,  maj_flt = 0;
        cputime_t cutime, cstime, utime, stime;
        unsigned long rsslim = 0;
-       struct task_struct *t;
        char tcomm[sizeof(task->comm)];
+       unsigned long flags;
 
        state = *get_task_state(task);
        vsize = eip = esp = 0;
@@ -349,15 +347,33 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
        cutime = cstime = utime = stime = cputime_zero;
 
        mutex_lock(&tty_mutex);
-       read_lock(&tasklist_lock);
-       if (task->sighand) {
-               spin_lock_irq(&task->sighand->siglock);
-               num_threads = atomic_read(&task->signal->count);
+       rcu_read_lock();
+       if (lock_task_sighand(task, &flags)) {
+               struct signal_struct *sig = task->signal;
+               struct tty_struct *tty = sig->tty;
+
+               if (tty) {
+                       /*
+                        * sig->tty is not stable, but tty_mutex
+                        * protects us from release_dev(tty)
+                        */
+                       barrier();
+                       tty_pgrp = tty->pgrp;
+                       tty_nr = new_encode_dev(tty_devnum(tty));
+               }
+
+               num_threads = atomic_read(&sig->count);
                collect_sigign_sigcatch(task, &sigign, &sigcatch);
 
+               cmin_flt = sig->cmin_flt;
+               cmaj_flt = sig->cmaj_flt;
+               cutime = sig->cutime;
+               cstime = sig->cstime;
+               rsslim = sig->rlim[RLIMIT_RSS].rlim_cur;
+
                /* add up live thread stats at the group level */
                if (whole) {
-                       t = task;
+                       struct task_struct *t = task;
                        do {
                                min_flt += t->min_flt;
                                maj_flt += t->maj_flt;
@@ -365,31 +381,20 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
                                stime = cputime_add(stime, t->stime);
                                t = next_thread(t);
                        } while (t != task);
-               }
 
-               spin_unlock_irq(&task->sighand->siglock);
-       }
-       if (task->signal) {
-               if (task->signal->tty) {
-                       tty_pgrp = task->signal->tty->pgrp;
-                       tty_nr = new_encode_dev(tty_devnum(task->signal->tty));
+                       min_flt += sig->min_flt;
+                       maj_flt += sig->maj_flt;
+                       utime = cputime_add(utime, sig->utime);
+                       stime = cputime_add(stime, sig->stime);
                }
+
+               sid = sig->session;
                pgid = process_group(task);
-               sid = task->signal->session;
-               cmin_flt = task->signal->cmin_flt;
-               cmaj_flt = task->signal->cmaj_flt;
-               cutime = task->signal->cutime;
-               cstime = task->signal->cstime;
-               rsslim = task->signal->rlim[RLIMIT_RSS].rlim_cur;
-               if (whole) {
-                       min_flt += task->signal->min_flt;
-                       maj_flt += task->signal->maj_flt;
-                       utime = cputime_add(utime, task->signal->utime);
-                       stime = cputime_add(stime, task->signal->stime);
-               }
+               ppid = rcu_dereference(task->real_parent)->tgid;
+
+               unlock_task_sighand(task, &flags);
        }
-       ppid = pid_alive(task) ? task->group_leader->real_parent->tgid : 0;
-       read_unlock(&tasklist_lock);
+       rcu_read_unlock();
        mutex_unlock(&tty_mutex);
 
        if (!whole || num_threads<2)
index 89c20d9d50bfbf09c77aca8ca921885bb7eb0084..82da55b5cffef804f4528bf1bed4d94645f7df2d 100644 (file)
@@ -71,6 +71,7 @@
 #include <linux/cpuset.h>
 #include <linux/audit.h>
 #include <linux/poll.h>
+#include <linux/nsproxy.h>
 #include "internal.h"
 
 /* NOTE:
  *     in /proc for a task before it execs a suid executable.
  */
 
-/*
- * For hysterical raisins we keep the same inumbers as in the old procfs.
- * Feel free to change the macro below - just keep the range distinct from
- * inumbers of the rest of procfs (currently those are in 0x0000--0xffff).
- * As soon as we'll get a separate superblock we will be able to forget
- * about magical ranges too.
- */
-
-#define fake_ino(pid,ino) (((pid)<<16)|(ino))
-
-enum pid_directory_inos {
-       PROC_TGID_INO = 2,
-       PROC_TGID_TASK,
-       PROC_TGID_STATUS,
-       PROC_TGID_MEM,
-#ifdef CONFIG_SECCOMP
-       PROC_TGID_SECCOMP,
-#endif
-       PROC_TGID_CWD,
-       PROC_TGID_ROOT,
-       PROC_TGID_EXE,
-       PROC_TGID_FD,
-       PROC_TGID_ENVIRON,
-       PROC_TGID_AUXV,
-       PROC_TGID_CMDLINE,
-       PROC_TGID_STAT,
-       PROC_TGID_STATM,
-       PROC_TGID_MAPS,
-       PROC_TGID_NUMA_MAPS,
-       PROC_TGID_MOUNTS,
-       PROC_TGID_MOUNTSTATS,
-       PROC_TGID_WCHAN,
-#ifdef CONFIG_MMU
-       PROC_TGID_SMAPS,
-#endif
-#ifdef CONFIG_SCHEDSTATS
-       PROC_TGID_SCHEDSTAT,
-#endif
-#ifdef CONFIG_CPUSETS
-       PROC_TGID_CPUSET,
-#endif
-#ifdef CONFIG_SECURITY
-       PROC_TGID_ATTR,
-       PROC_TGID_ATTR_CURRENT,
-       PROC_TGID_ATTR_PREV,
-       PROC_TGID_ATTR_EXEC,
-       PROC_TGID_ATTR_FSCREATE,
-       PROC_TGID_ATTR_KEYCREATE,
-       PROC_TGID_ATTR_SOCKCREATE,
-#endif
-#ifdef CONFIG_AUDITSYSCALL
-       PROC_TGID_LOGINUID,
-#endif
-       PROC_TGID_OOM_SCORE,
-       PROC_TGID_OOM_ADJUST,
-       PROC_TID_INO,
-       PROC_TID_STATUS,
-       PROC_TID_MEM,
-#ifdef CONFIG_SECCOMP
-       PROC_TID_SECCOMP,
-#endif
-       PROC_TID_CWD,
-       PROC_TID_ROOT,
-       PROC_TID_EXE,
-       PROC_TID_FD,
-       PROC_TID_ENVIRON,
-       PROC_TID_AUXV,
-       PROC_TID_CMDLINE,
-       PROC_TID_STAT,
-       PROC_TID_STATM,
-       PROC_TID_MAPS,
-       PROC_TID_NUMA_MAPS,
-       PROC_TID_MOUNTS,
-       PROC_TID_MOUNTSTATS,
-       PROC_TID_WCHAN,
-#ifdef CONFIG_MMU
-       PROC_TID_SMAPS,
-#endif
-#ifdef CONFIG_SCHEDSTATS
-       PROC_TID_SCHEDSTAT,
-#endif
-#ifdef CONFIG_CPUSETS
-       PROC_TID_CPUSET,
-#endif
-#ifdef CONFIG_SECURITY
-       PROC_TID_ATTR,
-       PROC_TID_ATTR_CURRENT,
-       PROC_TID_ATTR_PREV,
-       PROC_TID_ATTR_EXEC,
-       PROC_TID_ATTR_FSCREATE,
-       PROC_TID_ATTR_KEYCREATE,
-       PROC_TID_ATTR_SOCKCREATE,
-#endif
-#ifdef CONFIG_AUDITSYSCALL
-       PROC_TID_LOGINUID,
-#endif
-       PROC_TID_OOM_SCORE,
-       PROC_TID_OOM_ADJUST,
-
-       /* Add new entries before this */
-       PROC_TID_FD_DIR = 0x8000,       /* 0x8000-0xffff */
-};
 
 /* Worst case buffer size needed for holding an integer. */
 #define PROC_NUMBUF 10
 
 struct pid_entry {
-       int type;
        int len;
        char *name;
        mode_t mode;
+       struct inode_operations *iop;
+       struct file_operations *fop;
+       union proc_op op;
 };
 
-#define E(type,name,mode) {(type),sizeof(name)-1,(name),(mode)}
-
-static struct pid_entry tgid_base_stuff[] = {
-       E(PROC_TGID_TASK,      "task",    S_IFDIR|S_IRUGO|S_IXUGO),
-       E(PROC_TGID_FD,        "fd",      S_IFDIR|S_IRUSR|S_IXUSR),
-       E(PROC_TGID_ENVIRON,   "environ", S_IFREG|S_IRUSR),
-       E(PROC_TGID_AUXV,      "auxv",    S_IFREG|S_IRUSR),
-       E(PROC_TGID_STATUS,    "status",  S_IFREG|S_IRUGO),
-       E(PROC_TGID_CMDLINE,   "cmdline", S_IFREG|S_IRUGO),
-       E(PROC_TGID_STAT,      "stat",    S_IFREG|S_IRUGO),
-       E(PROC_TGID_STATM,     "statm",   S_IFREG|S_IRUGO),
-       E(PROC_TGID_MAPS,      "maps",    S_IFREG|S_IRUGO),
-#ifdef CONFIG_NUMA
-       E(PROC_TGID_NUMA_MAPS, "numa_maps", S_IFREG|S_IRUGO),
-#endif
-       E(PROC_TGID_MEM,       "mem",     S_IFREG|S_IRUSR|S_IWUSR),
-#ifdef CONFIG_SECCOMP
-       E(PROC_TGID_SECCOMP,   "seccomp", S_IFREG|S_IRUSR|S_IWUSR),
-#endif
-       E(PROC_TGID_CWD,       "cwd",     S_IFLNK|S_IRWXUGO),
-       E(PROC_TGID_ROOT,      "root",    S_IFLNK|S_IRWXUGO),
-       E(PROC_TGID_EXE,       "exe",     S_IFLNK|S_IRWXUGO),
-       E(PROC_TGID_MOUNTS,    "mounts",  S_IFREG|S_IRUGO),
-       E(PROC_TGID_MOUNTSTATS, "mountstats", S_IFREG|S_IRUSR),
-#ifdef CONFIG_MMU
-       E(PROC_TGID_SMAPS,     "smaps",   S_IFREG|S_IRUGO),
-#endif
-#ifdef CONFIG_SECURITY
-       E(PROC_TGID_ATTR,      "attr",    S_IFDIR|S_IRUGO|S_IXUGO),
-#endif
-#ifdef CONFIG_KALLSYMS
-       E(PROC_TGID_WCHAN,     "wchan",   S_IFREG|S_IRUGO),
-#endif
-#ifdef CONFIG_SCHEDSTATS
-       E(PROC_TGID_SCHEDSTAT, "schedstat", S_IFREG|S_IRUGO),
-#endif
-#ifdef CONFIG_CPUSETS
-       E(PROC_TGID_CPUSET,    "cpuset",  S_IFREG|S_IRUGO),
-#endif
-       E(PROC_TGID_OOM_SCORE, "oom_score",S_IFREG|S_IRUGO),
-       E(PROC_TGID_OOM_ADJUST,"oom_adj", S_IFREG|S_IRUGO|S_IWUSR),
-#ifdef CONFIG_AUDITSYSCALL
-       E(PROC_TGID_LOGINUID, "loginuid", S_IFREG|S_IWUSR|S_IRUGO),
-#endif
-       {0,0,NULL,0}
-};
-static struct pid_entry tid_base_stuff[] = {
-       E(PROC_TID_FD,         "fd",      S_IFDIR|S_IRUSR|S_IXUSR),
-       E(PROC_TID_ENVIRON,    "environ", S_IFREG|S_IRUSR),
-       E(PROC_TID_AUXV,       "auxv",    S_IFREG|S_IRUSR),
-       E(PROC_TID_STATUS,     "status",  S_IFREG|S_IRUGO),
-       E(PROC_TID_CMDLINE,    "cmdline", S_IFREG|S_IRUGO),
-       E(PROC_TID_STAT,       "stat",    S_IFREG|S_IRUGO),
-       E(PROC_TID_STATM,      "statm",   S_IFREG|S_IRUGO),
-       E(PROC_TID_MAPS,       "maps",    S_IFREG|S_IRUGO),
-#ifdef CONFIG_NUMA
-       E(PROC_TID_NUMA_MAPS,  "numa_maps",    S_IFREG|S_IRUGO),
-#endif
-       E(PROC_TID_MEM,        "mem",     S_IFREG|S_IRUSR|S_IWUSR),
-#ifdef CONFIG_SECCOMP
-       E(PROC_TID_SECCOMP,    "seccomp", S_IFREG|S_IRUSR|S_IWUSR),
-#endif
-       E(PROC_TID_CWD,        "cwd",     S_IFLNK|S_IRWXUGO),
-       E(PROC_TID_ROOT,       "root",    S_IFLNK|S_IRWXUGO),
-       E(PROC_TID_EXE,        "exe",     S_IFLNK|S_IRWXUGO),
-       E(PROC_TID_MOUNTS,     "mounts",  S_IFREG|S_IRUGO),
-#ifdef CONFIG_MMU
-       E(PROC_TID_SMAPS,      "smaps",   S_IFREG|S_IRUGO),
-#endif
-#ifdef CONFIG_SECURITY
-       E(PROC_TID_ATTR,       "attr",    S_IFDIR|S_IRUGO|S_IXUGO),
-#endif
-#ifdef CONFIG_KALLSYMS
-       E(PROC_TID_WCHAN,      "wchan",   S_IFREG|S_IRUGO),
-#endif
-#ifdef CONFIG_SCHEDSTATS
-       E(PROC_TID_SCHEDSTAT, "schedstat",S_IFREG|S_IRUGO),
-#endif
-#ifdef CONFIG_CPUSETS
-       E(PROC_TID_CPUSET,     "cpuset",  S_IFREG|S_IRUGO),
-#endif
-       E(PROC_TID_OOM_SCORE,  "oom_score",S_IFREG|S_IRUGO),
-       E(PROC_TID_OOM_ADJUST, "oom_adj", S_IFREG|S_IRUGO|S_IWUSR),
-#ifdef CONFIG_AUDITSYSCALL
-       E(PROC_TID_LOGINUID, "loginuid", S_IFREG|S_IWUSR|S_IRUGO),
-#endif
-       {0,0,NULL,0}
-};
-
-#ifdef CONFIG_SECURITY
-static struct pid_entry tgid_attr_stuff[] = {
-       E(PROC_TGID_ATTR_CURRENT,  "current",  S_IFREG|S_IRUGO|S_IWUGO),
-       E(PROC_TGID_ATTR_PREV,     "prev",     S_IFREG|S_IRUGO),
-       E(PROC_TGID_ATTR_EXEC,     "exec",     S_IFREG|S_IRUGO|S_IWUGO),
-       E(PROC_TGID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO),
-       E(PROC_TGID_ATTR_KEYCREATE, "keycreate", S_IFREG|S_IRUGO|S_IWUGO),
-       E(PROC_TGID_ATTR_SOCKCREATE, "sockcreate", S_IFREG|S_IRUGO|S_IWUGO),
-       {0,0,NULL,0}
-};
-static struct pid_entry tid_attr_stuff[] = {
-       E(PROC_TID_ATTR_CURRENT,   "current",  S_IFREG|S_IRUGO|S_IWUGO),
-       E(PROC_TID_ATTR_PREV,      "prev",     S_IFREG|S_IRUGO),
-       E(PROC_TID_ATTR_EXEC,      "exec",     S_IFREG|S_IRUGO|S_IWUGO),
-       E(PROC_TID_ATTR_FSCREATE,  "fscreate", S_IFREG|S_IRUGO|S_IWUGO),
-       E(PROC_TID_ATTR_KEYCREATE, "keycreate", S_IFREG|S_IRUGO|S_IWUGO),
-       E(PROC_TID_ATTR_SOCKCREATE, "sockcreate", S_IFREG|S_IRUGO|S_IWUGO),
-       {0,0,NULL,0}
-};
-#endif
-
-#undef E
-
-static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
-{
-       struct task_struct *task = get_proc_task(inode);
-       struct files_struct *files = NULL;
-       struct file *file;
-       int fd = proc_fd(inode);
-
-       if (task) {
-               files = get_files_struct(task);
-               put_task_struct(task);
-       }
-       if (files) {
-               /*
-                * We are not taking a ref to the file structure, so we must
-                * hold ->file_lock.
-                */
-               spin_lock(&files->file_lock);
-               file = fcheck_files(files, fd);
-               if (file) {
-                       *mnt = mntget(file->f_vfsmnt);
-                       *dentry = dget(file->f_dentry);
-                       spin_unlock(&files->file_lock);
-                       put_files_struct(files);
-                       return 0;
-               }
-               spin_unlock(&files->file_lock);
-               put_files_struct(files);
-       }
-       return -ENOENT;
+#define NOD(NAME, MODE, IOP, FOP, OP) {                        \
+       .len  = sizeof(NAME) - 1,                       \
+       .name = (NAME),                                 \
+       .mode = MODE,                                   \
+       .iop  = IOP,                                    \
+       .fop  = FOP,                                    \
+       .op   = OP,                                     \
 }
 
+#define DIR(NAME, MODE, OTYPE)                                                 \
+       NOD(NAME, (S_IFDIR|(MODE)),                                             \
+               &proc_##OTYPE##_inode_operations, &proc_##OTYPE##_operations,   \
+               {} )
+#define LNK(NAME, OTYPE)                                       \
+       NOD(NAME, (S_IFLNK|S_IRWXUGO),                          \
+               &proc_pid_link_inode_operations, NULL,          \
+               { .proc_get_link = &proc_##OTYPE##_link } )
+#define REG(NAME, MODE, OTYPE)                         \
+       NOD(NAME, (S_IFREG|(MODE)), NULL,               \
+               &proc_##OTYPE##_operations, {})
+#define INF(NAME, MODE, OTYPE)                         \
+       NOD(NAME, (S_IFREG|(MODE)),                     \
+               NULL, &proc_info_file_operations,       \
+               { .proc_read = &proc_##OTYPE } )
+
 static struct fs_struct *get_fs_struct(struct task_struct *task)
 {
        struct fs_struct *fs;
@@ -587,7 +370,7 @@ static int mounts_open(struct inode *inode, struct file *file)
 
        if (task) {
                task_lock(task);
-               namespace = task->namespace;
+               namespace = task->nsproxy->namespace;
                if (namespace)
                        get_namespace(namespace);
                task_unlock(task);
@@ -658,7 +441,7 @@ static int mountstats_open(struct inode *inode, struct file *file)
 
                if (task) {
                        task_lock(task);
-                       namespace = task->namespace;
+                       namespace = task->nsproxy->namespace;
                        if (namespace)
                                get_namespace(namespace);
                        task_unlock(task);
@@ -1137,143 +920,6 @@ static struct inode_operations proc_pid_link_inode_operations = {
        .setattr        = proc_setattr,
 };
 
-static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
-{
-       struct dentry *dentry = filp->f_dentry;
-       struct inode *inode = dentry->d_inode;
-       struct task_struct *p = get_proc_task(inode);
-       unsigned int fd, tid, ino;
-       int retval;
-       char buf[PROC_NUMBUF];
-       struct files_struct * files;
-       struct fdtable *fdt;
-
-       retval = -ENOENT;
-       if (!p)
-               goto out_no_task;
-       retval = 0;
-       tid = p->pid;
-
-       fd = filp->f_pos;
-       switch (fd) {
-               case 0:
-                       if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
-                               goto out;
-                       filp->f_pos++;
-               case 1:
-                       ino = parent_ino(dentry);
-                       if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
-                               goto out;
-                       filp->f_pos++;
-               default:
-                       files = get_files_struct(p);
-                       if (!files)
-                               goto out;
-                       rcu_read_lock();
-                       fdt = files_fdtable(files);
-                       for (fd = filp->f_pos-2;
-                            fd < fdt->max_fds;
-                            fd++, filp->f_pos++) {
-                               unsigned int i,j;
-
-                               if (!fcheck_files(files, fd))
-                                       continue;
-                               rcu_read_unlock();
-
-                               j = PROC_NUMBUF;
-                               i = fd;
-                               do {
-                                       j--;
-                                       buf[j] = '0' + (i % 10);
-                                       i /= 10;
-                               } while (i);
-
-                               ino = fake_ino(tid, PROC_TID_FD_DIR + fd);
-                               if (filldir(dirent, buf+j, PROC_NUMBUF-j, fd+2, ino, DT_LNK) < 0) {
-                                       rcu_read_lock();
-                                       break;
-                               }
-                               rcu_read_lock();
-                       }
-                       rcu_read_unlock();
-                       put_files_struct(files);
-       }
-out:
-       put_task_struct(p);
-out_no_task:
-       return retval;
-}
-
-static int proc_pident_readdir(struct file *filp,
-               void *dirent, filldir_t filldir,
-               struct pid_entry *ents, unsigned int nents)
-{
-       int i;
-       int pid;
-       struct dentry *dentry = filp->f_dentry;
-       struct inode *inode = dentry->d_inode;
-       struct task_struct *task = get_proc_task(inode);
-       struct pid_entry *p;
-       ino_t ino;
-       int ret;
-
-       ret = -ENOENT;
-       if (!task)
-               goto out;
-
-       ret = 0;
-       pid = task->pid;
-       put_task_struct(task);
-       i = filp->f_pos;
-       switch (i) {
-       case 0:
-               ino = inode->i_ino;
-               if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
-                       goto out;
-               i++;
-               filp->f_pos++;
-               /* fall through */
-       case 1:
-               ino = parent_ino(dentry);
-               if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0)
-                       goto out;
-               i++;
-               filp->f_pos++;
-               /* fall through */
-       default:
-               i -= 2;
-               if (i >= nents) {
-                       ret = 1;
-                       goto out;
-               }
-               p = ents + i;
-               while (p->name) {
-                       if (filldir(dirent, p->name, p->len, filp->f_pos,
-                                   fake_ino(pid, p->type), p->mode >> 12) < 0)
-                               goto out;
-                       filp->f_pos++;
-                       p++;
-               }
-       }
-
-       ret = 1;
-out:
-       return ret;
-}
-
-static int proc_tgid_base_readdir(struct file * filp,
-                            void * dirent, filldir_t filldir)
-{
-       return proc_pident_readdir(filp,dirent,filldir,
-                                  tgid_base_stuff,ARRAY_SIZE(tgid_base_stuff));
-}
-
-static int proc_tid_base_readdir(struct file * filp,
-                            void * dirent, filldir_t filldir)
-{
-       return proc_pident_readdir(filp,dirent,filldir,
-                                  tid_base_stuff,ARRAY_SIZE(tid_base_stuff));
-}
 
 /* building an inode */
 
@@ -1293,13 +939,13 @@ static int task_dumpable(struct task_struct *task)
 }
 
 
-static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task, int ino)
+static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task)
 {
        struct inode * inode;
        struct proc_inode *ei;
 
        /* We need a new inode */
-       
+
        inode = new_inode(sb);
        if (!inode)
                goto out;
@@ -1307,13 +953,12 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st
        /* Common stuff */
        ei = PROC_I(inode);
        inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
-       inode->i_ino = fake_ino(task->pid, ino);
        inode->i_op = &proc_def_inode_operations;
 
        /*
         * grab the reference to task.
         */
-       ei->pid = get_pid(task->pids[PIDTYPE_PID].pid);
+       ei->pid = get_task_pid(task, PIDTYPE_PID);
        if (!ei->pid)
                goto out_unlock;
 
@@ -1333,6 +978,27 @@ out_unlock:
        return NULL;
 }
 
+static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+{
+       struct inode *inode = dentry->d_inode;
+       struct task_struct *task;
+       generic_fillattr(inode, stat);
+
+       rcu_read_lock();
+       stat->uid = 0;
+       stat->gid = 0;
+       task = pid_task(proc_pid(inode), PIDTYPE_PID);
+       if (task) {
+               if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
+                   task_dumpable(task)) {
+                       stat->uid = task->euid;
+                       stat->gid = task->egid;
+               }
+       }
+       rcu_read_unlock();
+       return 0;
+}
+
 /* dentry stuff */
 
 /*
@@ -1372,25 +1038,130 @@ static int pid_revalidate(struct dentry *dentry, struct nameidata *nd)
        return 0;
 }
 
-static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+static int pid_delete_dentry(struct dentry * dentry)
 {
-       struct inode *inode = dentry->d_inode;
-       struct task_struct *task;
-       generic_fillattr(inode, stat);
-
-       rcu_read_lock();
-       stat->uid = 0;
-       stat->gid = 0;
-       task = pid_task(proc_pid(inode), PIDTYPE_PID);
+       /* Is the task we represent dead?
+        * If so, then don't put the dentry on the lru list,
+        * kill it immediately.
+        */
+       return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first;
+}
+
+static struct dentry_operations pid_dentry_operations =
+{
+       .d_revalidate   = pid_revalidate,
+       .d_delete       = pid_delete_dentry,
+};
+
+/* Lookups */
+
+typedef struct dentry *instantiate_t(struct inode *, struct dentry *, struct task_struct *, void *);
+
+/*
+ * Fill a directory entry.
+ *
+ * If possible create the dcache entry and derive our inode number and
+ * file type from dcache entry.
+ *
+ * Since all of the proc inode numbers are dynamically generated, the inode
+ * numbers do not exist until the inode is cache.  This means creating the
+ * the dcache entry in readdir is necessary to keep the inode numbers
+ * reported by readdir in sync with the inode numbers reported
+ * by stat.
+ */
+static int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
+       char *name, int len,
+       instantiate_t instantiate, struct task_struct *task, void *ptr)
+{
+       struct dentry *child, *dir = filp->f_dentry;
+       struct inode *inode;
+       struct qstr qname;
+       ino_t ino = 0;
+       unsigned type = DT_UNKNOWN;
+
+       qname.name = name;
+       qname.len  = len;
+       qname.hash = full_name_hash(name, len);
+
+       child = d_lookup(dir, &qname);
+       if (!child) {
+               struct dentry *new;
+               new = d_alloc(dir, &qname);
+               if (new) {
+                       child = instantiate(dir->d_inode, new, task, ptr);
+                       if (child)
+                               dput(new);
+                       else
+                               child = new;
+               }
+       }
+       if (!child || IS_ERR(child) || !child->d_inode)
+               goto end_instantiate;
+       inode = child->d_inode;
+       if (inode) {
+               ino = inode->i_ino;
+               type = inode->i_mode >> 12;
+       }
+       dput(child);
+end_instantiate:
+       if (!ino)
+               ino = find_inode_number(dir, &qname);
+       if (!ino)
+               ino = 1;
+       return filldir(dirent, name, len, filp->f_pos, ino, type);
+}
+
+static unsigned name_to_int(struct dentry *dentry)
+{
+       const char *name = dentry->d_name.name;
+       int len = dentry->d_name.len;
+       unsigned n = 0;
+
+       if (len > 1 && *name == '0')
+               goto out;
+       while (len-- > 0) {
+               unsigned c = *name++ - '0';
+               if (c > 9)
+                       goto out;
+               if (n >= (~0U-9)/10)
+                       goto out;
+               n *= 10;
+               n += c;
+       }
+       return n;
+out:
+       return ~0U;
+}
+
+static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
+{
+       struct task_struct *task = get_proc_task(inode);
+       struct files_struct *files = NULL;
+       struct file *file;
+       int fd = proc_fd(inode);
+
        if (task) {
-               if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
-                   task_dumpable(task)) {
-                       stat->uid = task->euid;
-                       stat->gid = task->egid;
+               files = get_files_struct(task);
+               put_task_struct(task);
+       }
+       if (files) {
+               /*
+                * We are not taking a ref to the file structure, so we must
+                * hold ->file_lock.
+                */
+               spin_lock(&files->file_lock);
+               file = fcheck_files(files, fd);
+               if (file) {
+                       *mnt = mntget(file->f_vfsmnt);
+                       *dentry = dget(file->f_dentry);
+                       spin_unlock(&files->file_lock);
+                       put_files_struct(files);
+                       return 0;
                }
+               spin_unlock(&files->file_lock);
+               put_files_struct(files);
        }
-       rcu_read_unlock();
-       return 0;
+       return -ENOENT;
 }
 
 static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
@@ -1428,75 +1199,30 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
        return 0;
 }
 
-static int pid_delete_dentry(struct dentry * dentry)
-{
-       /* Is the task we represent dead?
-        * If so, then don't put the dentry on the lru list,
-        * kill it immediately.
-        */
-       return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first;
-}
-
 static struct dentry_operations tid_fd_dentry_operations =
 {
        .d_revalidate   = tid_fd_revalidate,
        .d_delete       = pid_delete_dentry,
 };
 
-static struct dentry_operations pid_dentry_operations =
-{
-       .d_revalidate   = pid_revalidate,
-       .d_delete       = pid_delete_dentry,
-};
-
-/* Lookups */
-
-static unsigned name_to_int(struct dentry *dentry)
-{
-       const char *name = dentry->d_name.name;
-       int len = dentry->d_name.len;
-       unsigned n = 0;
-
-       if (len > 1 && *name == '0')
-               goto out;
-       while (len-- > 0) {
-               unsigned c = *name++ - '0';
-               if (c > 9)
-                       goto out;
-               if (n >= (~0U-9)/10)
-                       goto out;
-               n *= 10;
-               n += c;
-       }
-       return n;
-out:
-       return ~0U;
-}
-
-/* SMP-safe */
-static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
+static struct dentry *proc_fd_instantiate(struct inode *dir,
+       struct dentry *dentry, struct task_struct *task, void *ptr)
 {
-       struct task_struct *task = get_proc_task(dir);
-       unsigned fd = name_to_int(dentry);
-       struct dentry *result = ERR_PTR(-ENOENT);
-       struct file * file;
-       struct files_struct * files;
-       struct inode *inode;
-       struct proc_inode *ei;
-
-       if (!task)
-               goto out_no_task;
-       if (fd == ~0U)
-               goto out;
+       unsigned fd = *(unsigned *)ptr;
+       struct file *file;
+       struct files_struct *files;
+       struct inode *inode;
+       struct proc_inode *ei;
+       struct dentry *error = ERR_PTR(-ENOENT);
 
-       inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_FD_DIR+fd);
+       inode = proc_pid_make_inode(dir->i_sb, task);
        if (!inode)
                goto out;
        ei = PROC_I(inode);
        ei->fd = fd;
        files = get_files_struct(task);
        if (!files)
-               goto out_unlock;
+               goto out_iput;
        inode->i_mode = S_IFLNK;
 
        /*
@@ -1506,13 +1232,14 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
        spin_lock(&files->file_lock);
        file = fcheck_files(files, fd);
        if (!file)
-               goto out_unlock2;
+               goto out_unlock;
        if (file->f_mode & 1)
                inode->i_mode |= S_IRUSR | S_IXUSR;
        if (file->f_mode & 2)
                inode->i_mode |= S_IWUSR | S_IXUSR;
        spin_unlock(&files->file_lock);
        put_files_struct(files);
+
        inode->i_op = &proc_pid_link_inode_operations;
        inode->i_size = 64;
        ei->op.proc_get_link = proc_fd_link;
@@ -1520,34 +1247,106 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
        d_add(dentry, inode);
        /* Close the race of the process dying before we return the dentry */
        if (tid_fd_revalidate(dentry, NULL))
-               result = NULL;
-out:
-       put_task_struct(task);
-out_no_task:
-       return result;
+               error = NULL;
 
-out_unlock2:
+ out:
+       return error;
+out_unlock:
        spin_unlock(&files->file_lock);
        put_files_struct(files);
-out_unlock:
+out_iput:
        iput(inode);
        goto out;
 }
 
-static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldir);
-static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd);
-static int proc_task_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat);
+static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
+{
+       struct task_struct *task = get_proc_task(dir);
+       unsigned fd = name_to_int(dentry);
+       struct dentry *result = ERR_PTR(-ENOENT);
+
+       if (!task)
+               goto out_no_task;
+       if (fd == ~0U)
+               goto out;
+
+       result = proc_fd_instantiate(dir, dentry, task, &fd);
+out:
+       put_task_struct(task);
+out_no_task:
+       return result;
+}
+
+static int proc_fd_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
+       struct task_struct *task, int fd)
+{
+       char name[PROC_NUMBUF];
+       int len = snprintf(name, sizeof(name), "%d", fd);
+       return proc_fill_cache(filp, dirent, filldir, name, len,
+                               proc_fd_instantiate, task, &fd);
+}
+
+static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
+{
+       struct dentry *dentry = filp->f_dentry;
+       struct inode *inode = dentry->d_inode;
+       struct task_struct *p = get_proc_task(inode);
+       unsigned int fd, tid, ino;
+       int retval;
+       struct files_struct * files;
+       struct fdtable *fdt;
+
+       retval = -ENOENT;
+       if (!p)
+               goto out_no_task;
+       retval = 0;
+       tid = p->pid;
+
+       fd = filp->f_pos;
+       switch (fd) {
+               case 0:
+                       if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
+                               goto out;
+                       filp->f_pos++;
+               case 1:
+                       ino = parent_ino(dentry);
+                       if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
+                               goto out;
+                       filp->f_pos++;
+               default:
+                       files = get_files_struct(p);
+                       if (!files)
+                               goto out;
+                       rcu_read_lock();
+                       fdt = files_fdtable(files);
+                       for (fd = filp->f_pos-2;
+                            fd < fdt->max_fds;
+                            fd++, filp->f_pos++) {
+
+                               if (!fcheck_files(files, fd))
+                                       continue;
+                               rcu_read_unlock();
+
+                               if (proc_fd_fill_cache(filp, dirent, filldir, p, fd) < 0) {
+                                       rcu_read_lock();
+                                       break;
+                               }
+                               rcu_read_lock();
+                       }
+                       rcu_read_unlock();
+                       put_files_struct(files);
+       }
+out:
+       put_task_struct(p);
+out_no_task:
+       return retval;
+}
 
 static struct file_operations proc_fd_operations = {
        .read           = generic_read_dir,
        .readdir        = proc_readfd,
 };
 
-static struct file_operations proc_task_operations = {
-       .read           = generic_read_dir,
-       .readdir        = proc_task_readdir,
-};
-
 /*
  * proc directories can do almost nothing..
  */
@@ -1556,36 +1355,162 @@ static struct inode_operations proc_fd_inode_operations = {
        .setattr        = proc_setattr,
 };
 
-static struct inode_operations proc_task_inode_operations = {
-       .lookup         = proc_task_lookup,
-       .getattr        = proc_task_getattr,
-       .setattr        = proc_setattr,
-};
-
-#ifdef CONFIG_SECURITY
-static ssize_t proc_pid_attr_read(struct file * file, char __user * buf,
-                                 size_t count, loff_t *ppos)
+static struct dentry *proc_pident_instantiate(struct inode *dir,
+       struct dentry *dentry, struct task_struct *task, void *ptr)
 {
-       struct inode * inode = file->f_dentry->d_inode;
-       unsigned long page;
-       ssize_t length;
-       struct task_struct *task = get_proc_task(inode);
-
-       length = -ESRCH;
-       if (!task)
-               goto out_no_task;
+       struct pid_entry *p = ptr;
+       struct inode *inode;
+       struct proc_inode *ei;
+       struct dentry *error = ERR_PTR(-EINVAL);
 
-       if (count > PAGE_SIZE)
-               count = PAGE_SIZE;
-       length = -ENOMEM;
-       if (!(page = __get_free_page(GFP_KERNEL)))
+       inode = proc_pid_make_inode(dir->i_sb, task);
+       if (!inode)
                goto out;
 
-       length = security_getprocattr(task, 
-                                     (char*)file->f_dentry->d_name.name, 
-                                     (void*)page, count);
-       if (length >= 0)
-               length = simple_read_from_buffer(buf, count, ppos, (char *)page, length);
+       ei = PROC_I(inode);
+       inode->i_mode = p->mode;
+       if (S_ISDIR(inode->i_mode))
+               inode->i_nlink = 2;     /* Use getattr to fix if necessary */
+       if (p->iop)
+               inode->i_op = p->iop;
+       if (p->fop)
+               inode->i_fop = p->fop;
+       ei->op = p->op;
+       dentry->d_op = &pid_dentry_operations;
+       d_add(dentry, inode);
+       /* Close the race of the process dying before we return the dentry */
+       if (pid_revalidate(dentry, NULL))
+               error = NULL;
+out:
+       return error;
+}
+
+static struct dentry *proc_pident_lookup(struct inode *dir, 
+                                        struct dentry *dentry,
+                                        struct pid_entry *ents,
+                                        unsigned int nents)
+{
+       struct inode *inode;
+       struct dentry *error;
+       struct task_struct *task = get_proc_task(dir);
+       struct pid_entry *p, *last;
+
+       error = ERR_PTR(-ENOENT);
+       inode = NULL;
+
+       if (!task)
+               goto out_no_task;
+
+       /*
+        * Yes, it does not scale. And it should not. Don't add
+        * new entries into /proc/<tgid>/ without very good reasons.
+        */
+       last = &ents[nents - 1];
+       for (p = ents; p <= last; p++) {
+               if (p->len != dentry->d_name.len)
+                       continue;
+               if (!memcmp(dentry->d_name.name, p->name, p->len))
+                       break;
+       }
+       if (p > last)
+               goto out;
+
+       error = proc_pident_instantiate(dir, dentry, task, p);
+out:
+       put_task_struct(task);
+out_no_task:
+       return error;
+}
+
+static int proc_pident_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
+       struct task_struct *task, struct pid_entry *p)
+{
+       return proc_fill_cache(filp, dirent, filldir, p->name, p->len,
+                               proc_pident_instantiate, task, p);
+}
+
+static int proc_pident_readdir(struct file *filp,
+               void *dirent, filldir_t filldir,
+               struct pid_entry *ents, unsigned int nents)
+{
+       int i;
+       int pid;
+       struct dentry *dentry = filp->f_dentry;
+       struct inode *inode = dentry->d_inode;
+       struct task_struct *task = get_proc_task(inode);
+       struct pid_entry *p, *last;
+       ino_t ino;
+       int ret;
+
+       ret = -ENOENT;
+       if (!task)
+               goto out_no_task;
+
+       ret = 0;
+       pid = task->pid;
+       i = filp->f_pos;
+       switch (i) {
+       case 0:
+               ino = inode->i_ino;
+               if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
+                       goto out;
+               i++;
+               filp->f_pos++;
+               /* fall through */
+       case 1:
+               ino = parent_ino(dentry);
+               if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0)
+                       goto out;
+               i++;
+               filp->f_pos++;
+               /* fall through */
+       default:
+               i -= 2;
+               if (i >= nents) {
+                       ret = 1;
+                       goto out;
+               }
+               p = ents + i;
+               last = &ents[nents - 1];
+               while (p <= last) {
+                       if (proc_pident_fill_cache(filp, dirent, filldir, task, p) < 0)
+                               goto out;
+                       filp->f_pos++;
+                       p++;
+               }
+       }
+
+       ret = 1;
+out:
+       put_task_struct(task);
+out_no_task:
+       return ret;
+}
+
+#ifdef CONFIG_SECURITY
+static ssize_t proc_pid_attr_read(struct file * file, char __user * buf,
+                                 size_t count, loff_t *ppos)
+{
+       struct inode * inode = file->f_dentry->d_inode;
+       unsigned long page;
+       ssize_t length;
+       struct task_struct *task = get_proc_task(inode);
+
+       length = -ESRCH;
+       if (!task)
+               goto out_no_task;
+
+       if (count > PAGE_SIZE)
+               count = PAGE_SIZE;
+       length = -ENOMEM;
+       if (!(page = __get_free_page(GFP_KERNEL)))
+               goto out;
+
+       length = security_getprocattr(task,
+                                     (char*)file->f_dentry->d_name.name,
+                                     (void*)page, count);
+       if (length >= 0)
+               length = simple_read_from_buffer(buf, count, ppos, (char *)page, length);
        free_page(page);
 out:
        put_task_struct(task);
@@ -1595,17 +1520,17 @@ out_no_task:
 
 static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
                                   size_t count, loff_t *ppos)
-{ 
+{
        struct inode * inode = file->f_dentry->d_inode;
-       char *page; 
-       ssize_t length; 
+       char *page;
+       ssize_t length;
        struct task_struct *task = get_proc_task(inode);
 
        length = -ESRCH;
        if (!task)
                goto out_no_task;
-       if (count > PAGE_SIZE) 
-               count = PAGE_SIZE; 
+       if (count > PAGE_SIZE)
+               count = PAGE_SIZE;
 
        /* No partial writes. */
        length = -EINVAL;
@@ -1613,16 +1538,16 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
                goto out;
 
        length = -ENOMEM;
-       page = (char*)__get_free_page(GFP_USER); 
-       if (!page) 
+       page = (char*)__get_free_page(GFP_USER);
+       if (!page)
                goto out;
 
-       length = -EFAULT; 
-       if (copy_from_user(page, buf, count)) 
+       length = -EFAULT;
+       if (copy_from_user(page, buf, count))
                goto out_free;
 
-       length = security_setprocattr(task, 
-                                     (char*)file->f_dentry->d_name.name, 
+       length = security_setprocattr(task,
+                                     (char*)file->f_dentry->d_name.name,
                                      (void*)page, count);
 out_free:
        free_page((unsigned long) page);
@@ -1630,329 +1555,262 @@ out:
        put_task_struct(task);
 out_no_task:
        return length;
-} 
+}
 
 static struct file_operations proc_pid_attr_operations = {
        .read           = proc_pid_attr_read,
        .write          = proc_pid_attr_write,
 };
 
-static struct file_operations proc_tid_attr_operations;
-static struct inode_operations proc_tid_attr_inode_operations;
-static struct file_operations proc_tgid_attr_operations;
-static struct inode_operations proc_tgid_attr_inode_operations;
+static struct pid_entry attr_dir_stuff[] = {
+       REG("current",    S_IRUGO|S_IWUGO, pid_attr),
+       REG("prev",       S_IRUGO,         pid_attr),
+       REG("exec",       S_IRUGO|S_IWUGO, pid_attr),
+       REG("fscreate",   S_IRUGO|S_IWUGO, pid_attr),
+       REG("keycreate",  S_IRUGO|S_IWUGO, pid_attr),
+       REG("sockcreate", S_IRUGO|S_IWUGO, pid_attr),
+};
+
+static int proc_attr_dir_readdir(struct file * filp,
+                            void * dirent, filldir_t filldir)
+{
+       return proc_pident_readdir(filp,dirent,filldir,
+                                  attr_dir_stuff,ARRAY_SIZE(attr_dir_stuff));
+}
+
+static struct file_operations proc_attr_dir_operations = {
+       .read           = generic_read_dir,
+       .readdir        = proc_attr_dir_readdir,
+};
+
+static struct dentry *proc_attr_dir_lookup(struct inode *dir,
+                               struct dentry *dentry, struct nameidata *nd)
+{
+       return proc_pident_lookup(dir, dentry,
+                                 attr_dir_stuff, ARRAY_SIZE(attr_dir_stuff));
+}
+
+static struct inode_operations proc_attr_dir_inode_operations = {
+       .lookup         = proc_attr_dir_lookup,
+       .getattr        = pid_getattr,
+       .setattr        = proc_setattr,
+};
+
 #endif
 
-/* SMP-safe */
-static struct dentry *proc_pident_lookup(struct inode *dir, 
-                                        struct dentry *dentry,
-                                        struct pid_entry *ents)
+/*
+ * /proc/self:
+ */
+static int proc_self_readlink(struct dentry *dentry, char __user *buffer,
+                             int buflen)
 {
+       char tmp[PROC_NUMBUF];
+       sprintf(tmp, "%d", current->tgid);
+       return vfs_readlink(dentry,buffer,buflen,tmp);
+}
+
+static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+       char tmp[PROC_NUMBUF];
+       sprintf(tmp, "%d", current->tgid);
+       return ERR_PTR(vfs_follow_link(nd,tmp));
+}
+
+static struct inode_operations proc_self_inode_operations = {
+       .readlink       = proc_self_readlink,
+       .follow_link    = proc_self_follow_link,
+};
+
+/*
+ * proc base
+ *
+ * These are the directory entries in the root directory of /proc
+ * that properly belong to the /proc filesystem, as they describe
+ * describe something that is process related.
+ */
+static struct pid_entry proc_base_stuff[] = {
+       NOD("self", S_IFLNK|S_IRWXUGO,
+               &proc_self_inode_operations, NULL, {}),
+};
+
+/*
+ *     Exceptional case: normally we are not allowed to unhash a busy
+ * directory. In this case, however, we can do it - no aliasing problems
+ * due to the way we treat inodes.
+ */
+static int proc_base_revalidate(struct dentry *dentry, struct nameidata *nd)
+{
+       struct inode *inode = dentry->d_inode;
+       struct task_struct *task = get_proc_task(inode);
+       if (task) {
+               put_task_struct(task);
+               return 1;
+       }
+       d_drop(dentry);
+       return 0;
+}
+
+static struct dentry_operations proc_base_dentry_operations =
+{
+       .d_revalidate   = proc_base_revalidate,
+       .d_delete       = pid_delete_dentry,
+};
+
+static struct dentry *proc_base_instantiate(struct inode *dir,
+       struct dentry *dentry, struct task_struct *task, void *ptr)
+{
+       struct pid_entry *p = ptr;
        struct inode *inode;
+       struct proc_inode *ei;
+       struct dentry *error = ERR_PTR(-EINVAL);
+
+       /* Allocate the inode */
+       error = ERR_PTR(-ENOMEM);
+       inode = new_inode(dir->i_sb);
+       if (!inode)
+               goto out;
+
+       /* Initialize the inode */
+       ei = PROC_I(inode);
+       inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+
+       /*
+        * grab the reference to the task.
+        */
+       ei->pid = get_task_pid(task, PIDTYPE_PID);
+       if (!ei->pid)
+               goto out_iput;
+
+       inode->i_uid = 0;
+       inode->i_gid = 0;
+       inode->i_mode = p->mode;
+       if (S_ISDIR(inode->i_mode))
+               inode->i_nlink = 2;
+       if (S_ISLNK(inode->i_mode))
+               inode->i_size = 64;
+       if (p->iop)
+               inode->i_op = p->iop;
+       if (p->fop)
+               inode->i_fop = p->fop;
+       ei->op = p->op;
+       dentry->d_op = &proc_base_dentry_operations;
+       d_add(dentry, inode);
+       error = NULL;
+out:
+       return error;
+out_iput:
+       iput(inode);
+       goto out;
+}
+
+static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
+{
        struct dentry *error;
        struct task_struct *task = get_proc_task(dir);
-       struct pid_entry *p;
-       struct proc_inode *ei;
+       struct pid_entry *p, *last;
 
        error = ERR_PTR(-ENOENT);
-       inode = NULL;
 
        if (!task)
                goto out_no_task;
 
-       for (p = ents; p->name; p++) {
+       /* Lookup the directory entry */
+       last = &proc_base_stuff[ARRAY_SIZE(proc_base_stuff) - 1];
+       for (p = proc_base_stuff; p <= last; p++) {
                if (p->len != dentry->d_name.len)
                        continue;
                if (!memcmp(dentry->d_name.name, p->name, p->len))
                        break;
        }
-       if (!p->name)
+       if (p > last)
                goto out;
 
-       error = ERR_PTR(-EINVAL);
-       inode = proc_pid_make_inode(dir->i_sb, task, p->type);
-       if (!inode)
-               goto out;
+       error = proc_base_instantiate(dir, dentry, task, p);
 
-       ei = PROC_I(inode);
-       inode->i_mode = p->mode;
-       /*
-        * Yes, it does not scale. And it should not. Don't add
-        * new entries into /proc/<tgid>/ without very good reasons.
-        */
-       switch(p->type) {
-               case PROC_TGID_TASK:
-                       inode->i_nlink = 2;
-                       inode->i_op = &proc_task_inode_operations;
-                       inode->i_fop = &proc_task_operations;
-                       break;
-               case PROC_TID_FD:
-               case PROC_TGID_FD:
-                       inode->i_nlink = 2;
-                       inode->i_op = &proc_fd_inode_operations;
-                       inode->i_fop = &proc_fd_operations;
-                       break;
-               case PROC_TID_EXE:
-               case PROC_TGID_EXE:
-                       inode->i_op = &proc_pid_link_inode_operations;
-                       ei->op.proc_get_link = proc_exe_link;
-                       break;
-               case PROC_TID_CWD:
-               case PROC_TGID_CWD:
-                       inode->i_op = &proc_pid_link_inode_operations;
-                       ei->op.proc_get_link = proc_cwd_link;
-                       break;
-               case PROC_TID_ROOT:
-               case PROC_TGID_ROOT:
-                       inode->i_op = &proc_pid_link_inode_operations;
-                       ei->op.proc_get_link = proc_root_link;
-                       break;
-               case PROC_TID_ENVIRON:
-               case PROC_TGID_ENVIRON:
-                       inode->i_fop = &proc_info_file_operations;
-                       ei->op.proc_read = proc_pid_environ;
-                       break;
-               case PROC_TID_AUXV:
-               case PROC_TGID_AUXV:
-                       inode->i_fop = &proc_info_file_operations;
-                       ei->op.proc_read = proc_pid_auxv;
-                       break;
-               case PROC_TID_STATUS:
-               case PROC_TGID_STATUS:
-                       inode->i_fop = &proc_info_file_operations;
-                       ei->op.proc_read = proc_pid_status;
-                       break;
-               case PROC_TID_STAT:
-                       inode->i_fop = &proc_info_file_operations;
-                       ei->op.proc_read = proc_tid_stat;
-                       break;
-               case PROC_TGID_STAT:
-                       inode->i_fop = &proc_info_file_operations;
-                       ei->op.proc_read = proc_tgid_stat;
-                       break;
-               case PROC_TID_CMDLINE:
-               case PROC_TGID_CMDLINE:
-                       inode->i_fop = &proc_info_file_operations;
-                       ei->op.proc_read = proc_pid_cmdline;
-                       break;
-               case PROC_TID_STATM:
-               case PROC_TGID_STATM:
-                       inode->i_fop = &proc_info_file_operations;
-                       ei->op.proc_read = proc_pid_statm;
-                       break;
-               case PROC_TID_MAPS:
-               case PROC_TGID_MAPS:
-                       inode->i_fop = &proc_maps_operations;
-                       break;
+out:
+       put_task_struct(task);
+out_no_task:
+       return error;
+}
+
+static int proc_base_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
+       struct task_struct *task, struct pid_entry *p)
+{
+       return proc_fill_cache(filp, dirent, filldir, p->name, p->len,
+                               proc_base_instantiate, task, p);
+}
+
+/*
+ * Thread groups
+ */
+static struct file_operations proc_task_operations;
+static struct inode_operations proc_task_inode_operations;
+
+static struct pid_entry tgid_base_stuff[] = {
+       DIR("task",       S_IRUGO|S_IXUGO, task),
+       DIR("fd",         S_IRUSR|S_IXUSR, fd),
+       INF("environ",    S_IRUSR, pid_environ),
+       INF("auxv",       S_IRUSR, pid_auxv),
+       INF("status",     S_IRUGO, pid_status),
+       INF("cmdline",    S_IRUGO, pid_cmdline),
+       INF("stat",       S_IRUGO, tgid_stat),
+       INF("statm",      S_IRUGO, pid_statm),
+       REG("maps",       S_IRUGO, maps),
 #ifdef CONFIG_NUMA
-               case PROC_TID_NUMA_MAPS:
-               case PROC_TGID_NUMA_MAPS:
-                       inode->i_fop = &proc_numa_maps_operations;
-                       break;
+       REG("numa_maps",  S_IRUGO, numa_maps),
 #endif
-               case PROC_TID_MEM:
-               case PROC_TGID_MEM:
-                       inode->i_fop = &proc_mem_operations;
-                       break;
+       REG("mem",        S_IRUSR|S_IWUSR, mem),
 #ifdef CONFIG_SECCOMP
-               case PROC_TID_SECCOMP:
-               case PROC_TGID_SECCOMP:
-                       inode->i_fop = &proc_seccomp_operations;
-                       break;
-#endif /* CONFIG_SECCOMP */
-               case PROC_TID_MOUNTS:
-               case PROC_TGID_MOUNTS:
-                       inode->i_fop = &proc_mounts_operations;
-                       break;
+       REG("seccomp",    S_IRUSR|S_IWUSR, seccomp),
+#endif
+       LNK("cwd",        cwd),
+       LNK("root",       root),
+       LNK("exe",        exe),
+       REG("mounts",     S_IRUGO, mounts),
+       REG("mountstats", S_IRUSR, mountstats),
 #ifdef CONFIG_MMU
-               case PROC_TID_SMAPS:
-               case PROC_TGID_SMAPS:
-                       inode->i_fop = &proc_smaps_operations;
-                       break;
+       REG("smaps",      S_IRUGO, smaps),
 #endif
-               case PROC_TID_MOUNTSTATS:
-               case PROC_TGID_MOUNTSTATS:
-                       inode->i_fop = &proc_mountstats_operations;
-                       break;
 #ifdef CONFIG_SECURITY
-               case PROC_TID_ATTR:
-                       inode->i_nlink = 2;
-                       inode->i_op = &proc_tid_attr_inode_operations;
-                       inode->i_fop = &proc_tid_attr_operations;
-                       break;
-               case PROC_TGID_ATTR:
-                       inode->i_nlink = 2;
-                       inode->i_op = &proc_tgid_attr_inode_operations;
-                       inode->i_fop = &proc_tgid_attr_operations;
-                       break;
-               case PROC_TID_ATTR_CURRENT:
-               case PROC_TGID_ATTR_CURRENT:
-               case PROC_TID_ATTR_PREV:
-               case PROC_TGID_ATTR_PREV:
-               case PROC_TID_ATTR_EXEC:
-               case PROC_TGID_ATTR_EXEC:
-               case PROC_TID_ATTR_FSCREATE:
-               case PROC_TGID_ATTR_FSCREATE:
-               case PROC_TID_ATTR_KEYCREATE:
-               case PROC_TGID_ATTR_KEYCREATE:
-               case PROC_TID_ATTR_SOCKCREATE:
-               case PROC_TGID_ATTR_SOCKCREATE:
-                       inode->i_fop = &proc_pid_attr_operations;
-                       break;
+       DIR("attr",       S_IRUGO|S_IXUGO, attr_dir),
 #endif
 #ifdef CONFIG_KALLSYMS
-               case PROC_TID_WCHAN:
-               case PROC_TGID_WCHAN:
-                       inode->i_fop = &proc_info_file_operations;
-                       ei->op.proc_read = proc_pid_wchan;
-                       break;
+       INF("wchan",      S_IRUGO, pid_wchan),
 #endif
 #ifdef CONFIG_SCHEDSTATS
-               case PROC_TID_SCHEDSTAT:
-               case PROC_TGID_SCHEDSTAT:
-                       inode->i_fop = &proc_info_file_operations;
-                       ei->op.proc_read = proc_pid_schedstat;
-                       break;
+       INF("schedstat",  S_IRUGO, pid_schedstat),
 #endif
 #ifdef CONFIG_CPUSETS
-               case PROC_TID_CPUSET:
-               case PROC_TGID_CPUSET:
-                       inode->i_fop = &proc_cpuset_operations;
-                       break;
+       REG("cpuset",     S_IRUGO, cpuset),
 #endif
-               case PROC_TID_OOM_SCORE:
-               case PROC_TGID_OOM_SCORE:
-                       inode->i_fop = &proc_info_file_operations;
-                       ei->op.proc_read = proc_oom_score;
-                       break;
-               case PROC_TID_OOM_ADJUST:
-               case PROC_TGID_OOM_ADJUST:
-                       inode->i_fop = &proc_oom_adjust_operations;
-                       break;
+       INF("oom_score",  S_IRUGO, oom_score),
+       REG("oom_adj",    S_IRUGO|S_IWUSR, oom_adjust),
 #ifdef CONFIG_AUDITSYSCALL
-               case PROC_TID_LOGINUID:
-               case PROC_TGID_LOGINUID:
-                       inode->i_fop = &proc_loginuid_operations;
-                       break;
+       REG("loginuid",   S_IWUSR|S_IRUGO, loginuid),
 #endif
-               default:
-                       printk("procfs: impossible type (%d)",p->type);
-                       iput(inode);
-                       error = ERR_PTR(-EINVAL);
-                       goto out;
-       }
-       dentry->d_op = &pid_dentry_operations;
-       d_add(dentry, inode);
-       /* Close the race of the process dying before we return the dentry */
-       if (pid_revalidate(dentry, NULL))
-               error = NULL;
-out:
-       put_task_struct(task);
-out_no_task:
-       return error;
-}
-
-static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
-       return proc_pident_lookup(dir, dentry, tgid_base_stuff);
-}
-
-static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
-       return proc_pident_lookup(dir, dentry, tid_base_stuff);
-}
-
-static struct file_operations proc_tgid_base_operations = {
-       .read           = generic_read_dir,
-       .readdir        = proc_tgid_base_readdir,
 };
 
-static struct file_operations proc_tid_base_operations = {
-       .read           = generic_read_dir,
-       .readdir        = proc_tid_base_readdir,
-};
-
-static struct inode_operations proc_tgid_base_inode_operations = {
-       .lookup         = proc_tgid_base_lookup,
-       .getattr        = pid_getattr,
-       .setattr        = proc_setattr,
-};
-
-static struct inode_operations proc_tid_base_inode_operations = {
-       .lookup         = proc_tid_base_lookup,
-       .getattr        = pid_getattr,
-       .setattr        = proc_setattr,
-};
-
-#ifdef CONFIG_SECURITY
-static int proc_tgid_attr_readdir(struct file * filp,
-                            void * dirent, filldir_t filldir)
-{
-       return proc_pident_readdir(filp,dirent,filldir,
-                                  tgid_attr_stuff,ARRAY_SIZE(tgid_attr_stuff));
-}
-
-static int proc_tid_attr_readdir(struct file * filp,
-                            void * dirent, filldir_t filldir)
-{
-       return proc_pident_readdir(filp,dirent,filldir,
-                                  tid_attr_stuff,ARRAY_SIZE(tid_attr_stuff));
-}
-
-static struct file_operations proc_tgid_attr_operations = {
-       .read           = generic_read_dir,
-       .readdir        = proc_tgid_attr_readdir,
-};
-
-static struct file_operations proc_tid_attr_operations = {
-       .read           = generic_read_dir,
-       .readdir        = proc_tid_attr_readdir,
-};
-
-static struct dentry *proc_tgid_attr_lookup(struct inode *dir,
-                               struct dentry *dentry, struct nameidata *nd)
-{
-       return proc_pident_lookup(dir, dentry, tgid_attr_stuff);
-}
-
-static struct dentry *proc_tid_attr_lookup(struct inode *dir,
-                               struct dentry *dentry, struct nameidata *nd)
-{
-       return proc_pident_lookup(dir, dentry, tid_attr_stuff);
-}
-
-static struct inode_operations proc_tgid_attr_inode_operations = {
-       .lookup         = proc_tgid_attr_lookup,
-       .getattr        = pid_getattr,
-       .setattr        = proc_setattr,
-};
-
-static struct inode_operations proc_tid_attr_inode_operations = {
-       .lookup         = proc_tid_attr_lookup,
-       .getattr        = pid_getattr,
-       .setattr        = proc_setattr,
-};
-#endif
-
-/*
- * /proc/self:
- */
-static int proc_self_readlink(struct dentry *dentry, char __user *buffer,
-                             int buflen)
+static int proc_tgid_base_readdir(struct file * filp,
+                            void * dirent, filldir_t filldir)
 {
-       char tmp[PROC_NUMBUF];
-       sprintf(tmp, "%d", current->tgid);
-       return vfs_readlink(dentry,buffer,buflen,tmp);
+       return proc_pident_readdir(filp,dirent,filldir,
+                                  tgid_base_stuff,ARRAY_SIZE(tgid_base_stuff));
 }
 
-static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
-{
-       char tmp[PROC_NUMBUF];
-       sprintf(tmp, "%d", current->tgid);
-       return ERR_PTR(vfs_follow_link(nd,tmp));
-}      
+static struct file_operations proc_tgid_base_operations = {
+       .read           = generic_read_dir,
+       .readdir        = proc_tgid_base_readdir,
+};
 
-static struct inode_operations proc_self_inode_operations = {
-       .readlink       = proc_self_readlink,
-       .follow_link    = proc_self_follow_link,
+static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
+       return proc_pident_lookup(dir, dentry,
+                                 tgid_base_stuff, ARRAY_SIZE(tgid_base_stuff));
+}
+
+static struct inode_operations proc_tgid_base_inode_operations = {
+       .lookup         = proc_tgid_base_lookup,
+       .getattr        = pid_getattr,
+       .setattr        = proc_setattr,
 };
 
 /**
@@ -2022,54 +1880,23 @@ out:
        return;
 }
 
-/* SMP-safe */
-struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
+struct dentry *proc_pid_instantiate(struct inode *dir,
+       struct dentry * dentry, struct task_struct *task, void *ptr)
 {
-       struct dentry *result = ERR_PTR(-ENOENT);
-       struct task_struct *task;
+       struct dentry *error = ERR_PTR(-ENOENT);
        struct inode *inode;
-       struct proc_inode *ei;
-       unsigned tgid;
-
-       if (dentry->d_name.len == 4 && !memcmp(dentry->d_name.name,"self",4)) {
-               inode = new_inode(dir->i_sb);
-               if (!inode)
-                       return ERR_PTR(-ENOMEM);
-               ei = PROC_I(inode);
-               inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
-               inode->i_ino = fake_ino(0, PROC_TGID_INO);
-               ei->pde = NULL;
-               inode->i_mode = S_IFLNK|S_IRWXUGO;
-               inode->i_uid = inode->i_gid = 0;
-               inode->i_size = 64;
-               inode->i_op = &proc_self_inode_operations;
-               d_add(dentry, inode);
-               return NULL;
-       }
-       tgid = name_to_int(dentry);
-       if (tgid == ~0U)
-               goto out;
-
-       rcu_read_lock();
-       task = find_task_by_pid(tgid);
-       if (task)
-               get_task_struct(task);
-       rcu_read_unlock();
-       if (!task)
-               goto out;
 
-       inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO);
+       inode = proc_pid_make_inode(dir->i_sb, task);
        if (!inode)
-               goto out_put_task;
+               goto out;
 
        inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
        inode->i_op = &proc_tgid_base_inode_operations;
        inode->i_fop = &proc_tgid_base_operations;
        inode->i_flags|=S_IMMUTABLE;
-#ifdef CONFIG_SECURITY
-       inode->i_nlink = 5;
-#else
        inode->i_nlink = 4;
+#ifdef CONFIG_SECURITY
+       inode->i_nlink += 1;
 #endif
 
        dentry->d_op = &pid_dentry_operations;
@@ -2077,178 +1904,250 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct
        d_add(dentry, inode);
        /* Close the race of the process dying before we return the dentry */
        if (pid_revalidate(dentry, NULL))
-               result = NULL;
-
-out_put_task:
-       put_task_struct(task);
+               error = NULL;
 out:
-       return result;
+       return error;
 }
 
-/* SMP-safe */
-static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
+struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
 {
        struct dentry *result = ERR_PTR(-ENOENT);
        struct task_struct *task;
-       struct task_struct *leader = get_proc_task(dir);
-       struct inode *inode;
-       unsigned tid;
+       unsigned tgid;
 
-       if (!leader)
-               goto out_no_task;
+       result = proc_base_lookup(dir, dentry);
+       if (!IS_ERR(result) || PTR_ERR(result) != -ENOENT)
+               goto out;
 
-       tid = name_to_int(dentry);
-       if (tid == ~0U)
+       tgid = name_to_int(dentry);
+       if (tgid == ~0U)
                goto out;
 
        rcu_read_lock();
-       task = find_task_by_pid(tid);
+       task = find_task_by_pid(tgid);
        if (task)
                get_task_struct(task);
        rcu_read_unlock();
        if (!task)
                goto out;
-       if (leader->tgid != task->tgid)
-               goto out_drop_task;
-
-       inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_INO);
-
-
-       if (!inode)
-               goto out_drop_task;
-       inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
-       inode->i_op = &proc_tid_base_inode_operations;
-       inode->i_fop = &proc_tid_base_operations;
-       inode->i_flags|=S_IMMUTABLE;
-#ifdef CONFIG_SECURITY
-       inode->i_nlink = 4;
-#else
-       inode->i_nlink = 3;
-#endif
 
-       dentry->d_op = &pid_dentry_operations;
-
-       d_add(dentry, inode);
-       /* Close the race of the process dying before we return the dentry */
-       if (pid_revalidate(dentry, NULL))
-               result = NULL;
-
-out_drop_task:
+       result = proc_pid_instantiate(dir, dentry, task, NULL);
        put_task_struct(task);
 out:
-       put_task_struct(leader);
-out_no_task:
        return result;
 }
 
 /*
- * Find the first tgid to return to user space.
- *
- * Usually this is just whatever follows &init_task, but if the users
- * buffer was too small to hold the full list or there was a seek into
- * the middle of the directory we have more work to do.
- *
- * In the case of a short read we start with find_task_by_pid.
+ * Find the first task with tgid >= tgid
  *
- * In the case of a seek we start with &init_task and walk nr
- * threads past it.
  */
-static struct task_struct *first_tgid(int tgid, unsigned int nr)
+static struct task_struct *next_tgid(unsigned int tgid)
 {
-       struct task_struct *pos;
-       rcu_read_lock();
-       if (tgid && nr) {
-               pos = find_task_by_pid(tgid);
-               if (pos && thread_group_leader(pos))
-                       goto found;
-       }
-       /* If nr exceeds the number of processes get out quickly */
-       pos = NULL;
-       if (nr && nr >= nr_processes())
-               goto done;
+       struct task_struct *task;
+       struct pid *pid;
 
-       /* If we haven't found our starting place yet start with
-        * the init_task and walk nr tasks forward.
-        */
-       for (pos = next_task(&init_task); nr > 0; --nr) {
-               pos = next_task(pos);
-               if (pos == &init_task) {
-                       pos = NULL;
-                       goto done;
-               }
+       rcu_read_lock();
+retry:
+       task = NULL;
+       pid = find_ge_pid(tgid);
+       if (pid) {
+               tgid = pid->nr + 1;
+               task = pid_task(pid, PIDTYPE_PID);
+               /* What we to know is if the pid we have find is the
+                * pid of a thread_group_leader.  Testing for task
+                * being a thread_group_leader is the obvious thing
+                * todo but there is a window when it fails, due to
+                * the pid transfer logic in de_thread.
+                *
+                * So we perform the straight forward test of seeing
+                * if the pid we have found is the pid of a thread
+                * group leader, and don't worry if the task we have
+                * found doesn't happen to be a thread group leader.
+                * As we don't care in the case of readdir.
+                */
+               if (!task || !has_group_leader_pid(task))
+                       goto retry;
+               get_task_struct(task);
        }
-found:
-       get_task_struct(pos);
-done:
        rcu_read_unlock();
-       return pos;
+       return task;
 }
 
-/*
- * Find the next task in the task list.
- * Return NULL if we loop or there is any error.
- *
- * The reference to the input task_struct is released.
- */
-static struct task_struct *next_tgid(struct task_struct *start)
+#define TGID_OFFSET (FIRST_PROCESS_ENTRY + ARRAY_SIZE(proc_base_stuff))
+
+static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
+       struct task_struct *task, int tgid)
 {
-       struct task_struct *pos;
-       rcu_read_lock();
-       pos = start;
-       if (pid_alive(start))
-               pos = next_task(start);
-       if (pid_alive(pos) && (pos != &init_task)) {
-               get_task_struct(pos);
-               goto done;
-       }
-       pos = NULL;
-done:
-       rcu_read_unlock();
-       put_task_struct(start);
-       return pos;
+       char name[PROC_NUMBUF];
+       int len = snprintf(name, sizeof(name), "%d", tgid);
+       return proc_fill_cache(filp, dirent, filldir, name, len,
+                               proc_pid_instantiate, task, NULL);
 }
 
 /* for the /proc/ directory itself, after non-process stuff has been done */
 int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
 {
-       char buf[PROC_NUMBUF];
        unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
+       struct task_struct *reaper = get_proc_task(filp->f_dentry->d_inode);
        struct task_struct *task;
        int tgid;
 
-       if (!nr) {
-               ino_t ino = fake_ino(0,PROC_TGID_INO);
-               if (filldir(dirent, "self", 4, filp->f_pos, ino, DT_LNK) < 0)
-                       return 0;
-               filp->f_pos++;
-               nr++;
+       if (!reaper)
+               goto out_no_task;
+
+       for (; nr < ARRAY_SIZE(proc_base_stuff); filp->f_pos++, nr++) {
+               struct pid_entry *p = &proc_base_stuff[nr];
+               if (proc_base_fill_cache(filp, dirent, filldir, reaper, p) < 0)
+                       goto out;
        }
-       nr -= 1;
 
-       /* f_version caches the tgid value that the last readdir call couldn't
-        * return. lseek aka telldir automagically resets f_version to 0.
-        */
-       tgid = filp->f_version;
-       filp->f_version = 0;
-       for (task = first_tgid(tgid, nr);
+       tgid = filp->f_pos - TGID_OFFSET;
+       for (task = next_tgid(tgid);
             task;
-            task = next_tgid(task), filp->f_pos++) {
-               int len;
-               ino_t ino;
+            put_task_struct(task), task = next_tgid(tgid + 1)) {
                tgid = task->pid;
-               len = snprintf(buf, sizeof(buf), "%d", tgid);
-               ino = fake_ino(tgid, PROC_TGID_INO);
-               if (filldir(dirent, buf, len, filp->f_pos, ino, DT_DIR) < 0) {
-                       /* returning this tgid failed, save it as the first
-                        * pid for the next readir call */
-                       filp->f_version = tgid;
+               filp->f_pos = tgid + TGID_OFFSET;
+               if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) {
                        put_task_struct(task);
-                       break;
+                       goto out;
                }
        }
+       filp->f_pos = PID_MAX_LIMIT + TGID_OFFSET;
+out:
+       put_task_struct(reaper);
+out_no_task:
        return 0;
 }
 
+/*
+ * Tasks
+ */
+static struct pid_entry tid_base_stuff[] = {
+       DIR("fd",        S_IRUSR|S_IXUSR, fd),
+       INF("environ",   S_IRUSR, pid_environ),
+       INF("auxv",      S_IRUSR, pid_auxv),
+       INF("status",    S_IRUGO, pid_status),
+       INF("cmdline",   S_IRUGO, pid_cmdline),
+       INF("stat",      S_IRUGO, tid_stat),
+       INF("statm",     S_IRUGO, pid_statm),
+       REG("maps",      S_IRUGO, maps),
+#ifdef CONFIG_NUMA
+       REG("numa_maps", S_IRUGO, numa_maps),
+#endif
+       REG("mem",       S_IRUSR|S_IWUSR, mem),
+#ifdef CONFIG_SECCOMP
+       REG("seccomp",   S_IRUSR|S_IWUSR, seccomp),
+#endif
+       LNK("cwd",       cwd),
+       LNK("root",      root),
+       LNK("exe",       exe),
+       REG("mounts",    S_IRUGO, mounts),
+#ifdef CONFIG_MMU
+       REG("smaps",     S_IRUGO, smaps),
+#endif
+#ifdef CONFIG_SECURITY
+       DIR("attr",      S_IRUGO|S_IXUGO, attr_dir),
+#endif
+#ifdef CONFIG_KALLSYMS
+       INF("wchan",     S_IRUGO, pid_wchan),
+#endif
+#ifdef CONFIG_SCHEDSTATS
+       INF("schedstat", S_IRUGO, pid_schedstat),
+#endif
+#ifdef CONFIG_CPUSETS
+       REG("cpuset",    S_IRUGO, cpuset),
+#endif
+       INF("oom_score", S_IRUGO, oom_score),
+       REG("oom_adj",   S_IRUGO|S_IWUSR, oom_adjust),
+#ifdef CONFIG_AUDITSYSCALL
+       REG("loginuid",  S_IWUSR|S_IRUGO, loginuid),
+#endif
+};
+
+static int proc_tid_base_readdir(struct file * filp,
+                            void * dirent, filldir_t filldir)
+{
+       return proc_pident_readdir(filp,dirent,filldir,
+                                  tid_base_stuff,ARRAY_SIZE(tid_base_stuff));
+}
+
+static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
+       return proc_pident_lookup(dir, dentry,
+                                 tid_base_stuff, ARRAY_SIZE(tid_base_stuff));
+}
+
+static struct file_operations proc_tid_base_operations = {
+       .read           = generic_read_dir,
+       .readdir        = proc_tid_base_readdir,
+};
+
+static struct inode_operations proc_tid_base_inode_operations = {
+       .lookup         = proc_tid_base_lookup,
+       .getattr        = pid_getattr,
+       .setattr        = proc_setattr,
+};
+
+static struct dentry *proc_task_instantiate(struct inode *dir,
+       struct dentry *dentry, struct task_struct *task, void *ptr)
+{
+       struct dentry *error = ERR_PTR(-ENOENT);
+       struct inode *inode;
+       inode = proc_pid_make_inode(dir->i_sb, task);
+
+       if (!inode)
+               goto out;
+       inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
+       inode->i_op = &proc_tid_base_inode_operations;
+       inode->i_fop = &proc_tid_base_operations;
+       inode->i_flags|=S_IMMUTABLE;
+       inode->i_nlink = 3;
+#ifdef CONFIG_SECURITY
+       inode->i_nlink += 1;
+#endif
+
+       dentry->d_op = &pid_dentry_operations;
+
+       d_add(dentry, inode);
+       /* Close the race of the process dying before we return the dentry */
+       if (pid_revalidate(dentry, NULL))
+               error = NULL;
+out:
+       return error;
+}
+
+static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
+{
+       struct dentry *result = ERR_PTR(-ENOENT);
+       struct task_struct *task;
+       struct task_struct *leader = get_proc_task(dir);
+       unsigned tid;
+
+       if (!leader)
+               goto out_no_task;
+
+       tid = name_to_int(dentry);
+       if (tid == ~0U)
+               goto out;
+
+       rcu_read_lock();
+       task = find_task_by_pid(tid);
+       if (task)
+               get_task_struct(task);
+       rcu_read_unlock();
+       if (!task)
+               goto out;
+       if (leader->tgid != task->tgid)
+               goto out_drop_task;
+
+       result = proc_task_instantiate(dir, dentry, task, NULL);
+out_drop_task:
+       put_task_struct(task);
+out:
+       put_task_struct(leader);
+out_no_task:
+       return result;
+}
+
 /*
  * Find the first tid of a thread group to return to user space.
  *
@@ -2318,10 +2217,18 @@ static struct task_struct *next_tid(struct task_struct *start)
        return pos;
 }
 
+static int proc_task_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
+       struct task_struct *task, int tid)
+{
+       char name[PROC_NUMBUF];
+       int len = snprintf(name, sizeof(name), "%d", tid);
+       return proc_fill_cache(filp, dirent, filldir, name, len,
+                               proc_task_instantiate, task, NULL);
+}
+
 /* for the /proc/TGID/task/ directories */
 static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldir)
 {
-       char buf[PROC_NUMBUF];
        struct dentry *dentry = filp->f_dentry;
        struct inode *inode = dentry->d_inode;
        struct task_struct *leader = get_proc_task(inode);
@@ -2358,11 +2265,8 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi
        for (task = first_tid(leader, tid, pos - 2);
             task;
             task = next_tid(task), pos++) {
-               int len;
                tid = task->pid;
-               len = snprintf(buf, sizeof(buf), "%d", tid);
-               ino = fake_ino(tid, PROC_TID_INO);
-               if (filldir(dirent, buf, len, pos, ino, DT_DIR < 0)) {
+               if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) {
                        /* returning this tgid failed, save it as the first
                         * pid for the next readir call */
                        filp->f_version = tid;
@@ -2392,3 +2296,14 @@ static int proc_task_getattr(struct vfsmount *mnt, struct dentry *dentry, struct
 
        return 0;
 }
+
+static struct inode_operations proc_task_inode_operations = {
+       .lookup         = proc_task_lookup,
+       .getattr        = proc_task_getattr,
+       .setattr        = proc_setattr,
+};
+
+static struct file_operations proc_task_operations = {
+       .read           = generic_read_dir,
+       .readdir        = proc_task_readdir,
+};
index 66bc425f2f3db467344dd81c841442c5806b985e..8d88e58ed5cca648a75a514766f41a80f883d5d7 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/sysrq.h>
 #include <linux/vmalloc.h>
 #include <linux/crash_dump.h>
+#include <linux/pspace.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
@@ -91,7 +92,7 @@ static int loadavg_read_proc(char *page, char **start, off_t off,
                LOAD_INT(a), LOAD_FRAC(a),
                LOAD_INT(b), LOAD_FRAC(b),
                LOAD_INT(c), LOAD_FRAC(c),
-               nr_running(), nr_threads, last_pid);
+               nr_running(), nr_threads, init_pspace.last_pid);
        return proc_calc_metrics(page, start, off, count, eof, len);
 }
 
index 8901c65caca83be55d575ea70d51411435d5410e..ffe66c38488b6d6925614e00147d213dfc271e0f 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/bitops.h>
 #include <linux/smp_lock.h>
+#include <linux/mount.h>
 
 #include "internal.h"
 
@@ -28,6 +29,17 @@ struct proc_dir_entry *proc_sys_root;
 static int proc_get_sb(struct file_system_type *fs_type,
        int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
+       if (proc_mnt) {
+               /* Seed the root directory with a pid so it doesn't need
+                * to be special in base.c.  I would do this earlier but
+                * the only task alive when /proc is mounted the first time
+                * is the init_task and it doesn't have any pids.
+                */
+               struct proc_inode *ei;
+               ei = PROC_I(proc_mnt->mnt_sb->s_root->d_inode);
+               if (!ei->pid)
+                       ei->pid = find_get_pid(1);
+       }
        return get_sb_single(fs_type, flags, data, proc_fill_super, mnt);
 }
 
index b6109329b60739197685270d833b0699d11c020d..bff3ee58e2f86ecd8e599e104b46e7faa04752f5 100644 (file)
@@ -69,20 +69,24 @@ struct readdir_callback {
 };
 
 static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset,
-                     ino_t ino, unsigned int d_type)
+                     u64 ino, unsigned int d_type)
 {
        struct readdir_callback * buf = (struct readdir_callback *) __buf;
        struct old_linux_dirent __user * dirent;
+       unsigned long d_ino;
 
        if (buf->result)
                return -EINVAL;
+       d_ino = ino;
+       if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+               return -EOVERFLOW;
        buf->result++;
        dirent = buf->dirent;
        if (!access_ok(VERIFY_WRITE, dirent,
                        (unsigned long)(dirent->d_name + namlen + 1) -
                                (unsigned long)dirent))
                goto efault;
-       if (    __put_user(ino, &dirent->d_ino) ||
+       if (    __put_user(d_ino, &dirent->d_ino) ||
                __put_user(offset, &dirent->d_offset) ||
                __put_user(namlen, &dirent->d_namlen) ||
                __copy_to_user(dirent->d_name, name, namlen) ||
@@ -138,22 +142,26 @@ struct getdents_callback {
 };
 
 static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
-                  ino_t ino, unsigned int d_type)
+                  u64 ino, unsigned int d_type)
 {
        struct linux_dirent __user * dirent;
        struct getdents_callback * buf = (struct getdents_callback *) __buf;
+       unsigned long d_ino;
        int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2);
 
        buf->error = -EINVAL;   /* only used if we fail.. */
        if (reclen > buf->count)
                return -EINVAL;
+       d_ino = ino;
+       if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+               return -EOVERFLOW;
        dirent = buf->previous;
        if (dirent) {
                if (__put_user(offset, &dirent->d_off))
                        goto efault;
        }
        dirent = buf->current_dir;
-       if (__put_user(ino, &dirent->d_ino))
+       if (__put_user(d_ino, &dirent->d_ino))
                goto efault;
        if (__put_user(reclen, &dirent->d_reclen))
                goto efault;
@@ -222,7 +230,7 @@ struct getdents_callback64 {
 };
 
 static int filldir64(void * __buf, const char * name, int namlen, loff_t offset,
-                    ino_t ino, unsigned int d_type)
+                    u64 ino, unsigned int d_type)
 {
        struct linux_dirent64 __user *dirent;
        struct getdents_callback64 * buf = (struct getdents_callback64 *) __buf;
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 d935fb9394e360866cfa650ca6704bdd229c044d..7bdb0ed443e1155bdd7b40b8e26a417f2d96be1c 100644 (file)
@@ -773,7 +773,7 @@ int reiserfs_xattr_del(struct inode *inode, const char *name)
 
 static int
 reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen,
-                             loff_t offset, ino_t ino, unsigned int d_type)
+                             loff_t offset, u64 ino, unsigned int d_type)
 {
        struct dentry *xadir = (struct dentry *)buf;
 
@@ -851,7 +851,7 @@ struct reiserfs_chown_buf {
 /* XXX: If there is a better way to do this, I'd love to hear about it */
 static int
 reiserfs_chown_xattrs_filler(void *buf, const char *name, int namelen,
-                            loff_t offset, ino_t ino, unsigned int d_type)
+                            loff_t offset, u64 ino, unsigned int d_type)
 {
        struct reiserfs_chown_buf *chown_buf = (struct reiserfs_chown_buf *)buf;
        struct dentry *xafile, *xadir = chown_buf->xadir;
@@ -1036,7 +1036,7 @@ struct reiserfs_listxattr_buf {
 
 static int
 reiserfs_listxattr_filler(void *buf, const char *name, int namelen,
-                         loff_t offset, ino_t ino, unsigned int d_type)
+                         loff_t offset, u64 ino, unsigned int d_type)
 {
        struct reiserfs_listxattr_buf *b = (struct reiserfs_listxattr_buf *)buf;
        int len = 0;
index 60a31d5e5966a03ba0a3e009ae521bf02ade2adb..bca07eb2003c395b8e40d33cfe3ce548065d9ff7 100644 (file)
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -140,6 +140,8 @@ static int cp_old_stat(struct kstat *stat, struct __old_kernel_stat __user * sta
        memset(&tmp, 0, sizeof(struct __old_kernel_stat));
        tmp.st_dev = old_encode_dev(stat->dev);
        tmp.st_ino = stat->ino;
+       if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
+               return -EOVERFLOW;
        tmp.st_mode = stat->mode;
        tmp.st_nlink = stat->nlink;
        if (tmp.st_nlink != stat->nlink)
@@ -210,6 +212,8 @@ static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf)
        tmp.st_dev = new_encode_dev(stat->dev);
 #endif
        tmp.st_ino = stat->ino;
+       if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
+               return -EOVERFLOW;
        tmp.st_mode = stat->mode;
        tmp.st_nlink = stat->nlink;
        if (tmp.st_nlink != stat->nlink)
@@ -347,6 +351,8 @@ static long cp_new_stat64(struct kstat *stat, struct stat64 __user *statbuf)
        tmp.st_rdev = huge_encode_dev(stat->rdev);
 #endif
        tmp.st_ino = stat->ino;
+       if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
+               return -EOVERFLOW;
 #ifdef STAT64_HAS_BROKEN_ST_INO
        tmp.__st_ino = stat->ino;
 #endif
index cf3786625bfade2ec42b0bcebcd6b0c72771ff21..146f1dedec844ced95a9055e31e701365b4b241e 100644 (file)
@@ -157,8 +157,8 @@ sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos)
                if ((retval = fill_read_buffer(file->f_dentry,buffer)))
                        goto out;
        }
-       pr_debug("%s: count = %d, ppos = %lld, buf = %s\n",
-                __FUNCTION__,count,*ppos,buffer->page);
+       pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n",
+                __FUNCTION__, count, *ppos, buffer->page);
        retval = flush_read_buffer(buffer,buf,count,ppos);
 out:
        up(&buffer->sem);
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 bc6e6a9259dceae583af27b0c5bda3b33f21d323..2cabbd465c0c4d1b3437dafea1bf7030b080c217 100644 (file)
@@ -580,75 +580,6 @@ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, type6 arg6)\
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/signal.h>
-#include <linux/syscalls.h>
-#include <asm/ptrace.h>
-
-static inline long open(const char * name, int mode, int flags)
-{
-       return sys_open(name, mode, flags);
-}
-
-static inline long dup(int fd)
-{
-       return sys_dup(fd);
-}
-
-static inline long close(int fd)
-{
-       return sys_close(fd);
-}
-
-static inline off_t lseek(int fd, off_t off, int whence)
-{
-       return sys_lseek(fd, off, whence);
-}
-
-static inline void _exit(int value)
-{
-       sys_exit(value);
-}
-
-#define exit(x) _exit(x)
-
-static inline long write(int fd, const char * buf, size_t nr)
-{
-       return sys_write(fd, buf, nr);
-}
-
-static inline long read(int fd, char * buf, size_t nr)
-{
-       return sys_read(fd, buf, nr);
-}
-
-extern int execve(char *, char **, char **);
-
-static inline long setsid(void)
-{
-       return sys_setsid();
-}
-
-static inline pid_t waitpid(int pid, int * wait_stat, int flags)
-{
-       return sys_wait4(pid, wait_stat, flags, NULL);
-}
-
-asmlinkage int sys_execve(char *ufilename, char **argv, char **envp,
-                       unsigned long a3, unsigned long a4, unsigned long a5,
-                       struct pt_regs regs);
-asmlinkage long sys_rt_sigaction(int sig,
-                               const struct sigaction __user *act,
-                               struct sigaction __user *oact,
-                               size_t sigsetsize,
-                               void *restorer);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 /* "Conditional" syscalls.  What we want is
 
        __attribute__((weak,alias("sys_ni_syscall")))
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 91ae0030fdf28e4a8e808e67047da8d1d3060963..ce155e1612690dbf7671f9c0d95a20aa9ef0ac51 100644 (file)
@@ -32,6 +32,7 @@ struct clk;
 #define KEYCLKCTRL_REG         (PWRMAN_VA_BASE + 0xb0)
 #define TSCLKCTRL_REG          (PWRMAN_VA_BASE + 0xb4)
 #define PWMCLKCTRL_REG         (PWRMAN_VA_BASE + 0xb8)
+#define TIMCLKCTRL_REG         (PWRMAN_VA_BASE + 0xbc)
 #define SPICTRL_REG            (PWRMAN_VA_BASE + 0xc4)
 #define FLASHCLKCTRL_REG       (PWRMAN_VA_BASE + 0xc8)
 #define UART3CLK_REG           (PWRMAN_VA_BASE + 0xd0)
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 aba9b30f42490cbcfe6aab1e090662755cf0b913..81c3928d608c8182dae4d266d67ad247f119e845 100644 (file)
  *  published by the Free Software Foundation.
  */
 
+#include <linux/fb.h>
+
 /*
  * This structure describes the machine which we are running on.
  * It is set in linux/arch/arm/mach-pxa/machine_name.c and used in the probe routine
  * of linux/drivers/video/pxafb.c
  */
-struct pxafb_mach_info {
+struct pxafb_mode_info {
        u_long          pixclock;
 
        u_short         xres;
@@ -34,6 +36,14 @@ struct pxafb_mach_info {
        u_char          sync;
 
        u_int           cmap_greyscale:1,
+                       unused:31;
+};
+
+struct pxafb_mach_info {
+       struct pxafb_mode_info *modes;
+       unsigned int num_modes;
+
+       u_int           fixed_modes:1,
                        cmap_inverse:1,
                        cmap_static:1,
                        unused:29;
@@ -62,7 +72,7 @@ struct pxafb_mach_info {
        u_int           lccr3;
 
        void (*pxafb_backlight_power)(int);
-       void (*pxafb_lcd_power)(int);
+       void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *);
 
 };
 void set_pxa_fb_info(struct pxafb_mach_info *hard_pxa_fb_info);
index 62e1fe4d025f96a6f527d09e4a8ed20e705333fa..4953dd324d4d1e51630c48bce3d15eaf05a3a426 100644 (file)
@@ -15,6 +15,8 @@
 #define __ASM_ARCH_SPITZ_H  1
 #endif
 
+#include <linux/fb.h>
+
 /* Spitz/Akita GPIOs */
 
 #define SPITZ_GPIO_KEY_INT         (0) /* Key Interrupt */
@@ -155,4 +157,4 @@ extern struct platform_device spitzscoop2_device;
 extern struct platform_device spitzssp_device;
 extern struct sharpsl_charger_machinfo spitz_pm_machinfo;
 
-extern void spitz_lcd_power(int on);
+extern void spitz_lcd_power(int on, struct fb_var_screeninfo *var);
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>
  *
diff --git a/include/asm-arm/timeofday.h b/include/asm-arm/timeofday.h
deleted file mode 100644 (file)
index 27254bd..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef _ASM_ARM_TIMEOFDAY_H
-#define _ASM_ARM_TIMEOFDAY_H
-#include <asm-generic/timeofday.h>
-#endif
index 2ab4078334bf1ee57afba6e6ffa7639903dd6889..14a87eec5a2dd28662173173316bf1a9ffa29ac6 100644 (file)
@@ -549,30 +549,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
 #define __ARCH_WANT_SYS_SOCKETCALL
 #endif
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/syscalls.h>
-
-extern long execve(const char *file, char **argv, char **envp);
-
-struct pt_regs;
-asmlinkage int sys_execve(char *filenamei, char **argv, char **envp,
-                       struct pt_regs *regs);
-asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
-                       struct pt_regs *regs);
-asmlinkage int sys_fork(struct pt_regs *regs);
-asmlinkage int sys_vfork(struct pt_regs *regs);
-asmlinkage int sys_pipe(unsigned long *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-                               const struct sigaction __user *act,
-                               struct sigaction __user *oact,
-                               size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  *
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 c6d2436c9d349ca322790a81fe95181988641da0..25a5eead85beaa4a26530f9d331519edc6270ffe 100644 (file)
@@ -464,30 +464,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/syscalls.h>
-
-extern long execve(const char *file, char **argv, char **envp);
-
-struct pt_regs;
-asmlinkage int sys_execve(char *filenamei, char **argv, char **envp,
-                       struct pt_regs *regs);
-asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
-                       struct pt_regs *regs);
-asmlinkage int sys_fork(struct pt_regs *regs);
-asmlinkage int sys_vfork(struct pt_regs *regs);
-asmlinkage int sys_pipe(unsigned long *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-                               const struct sigaction __user *act,
-                               struct sigaction __user *oact,
-                               size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  *
index 1f528f92690d48fba210eecfeff3c0436211cc77..a50e5004550c5d506d23b33db1a5bea490d50e84 100644 (file)
 #define __NR_tee               263
 #define __NR_vmsplice          264
 
+#ifdef __KERNEL__
 #define NR_syscalls            265
 
 
-/*
- * AVR32 calling convention for system calls:
- *   - System call number in r8
- *   - Parameters in r12 and downwards to r9 as well as r6 and r5.
- *   - Return value in r12
- */
-
-/*
- * user-visible error numbers are in the range -1 - -124: see
- * <asm-generic/errno.h>
- */
-
-#define __syscall_return(type, res) do {                               \
-               if ((unsigned long)(res) >= (unsigned long)(-125)) {    \
-                       errno = -(res);                                 \
-                       res = -1;                                       \
-               }                                                       \
-               return (type) (res);                                    \
-       } while (0)
-
-#ifdef __KERNEL__
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETPGRP
 #define __ARCH_WANT_SYS_RT_SIGACTION
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
-#endif
-
-#if defined(__KERNEL_SYSCALLS__) || defined(__CHECKER__)
-
-#include <linux/types.h>
-#include <linux/linkage.h>
-#include <asm/signal.h>
-
-struct pt_regs;
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-static inline int execve(const char *file, char **argv, char **envp)
-{
-       register long scno asm("r8") = __NR_execve;
-       register long sc1 asm("r12") = (long)file;
-       register long sc2 asm("r11") = (long)argv;
-       register long sc3 asm("r10") = (long)envp;
-       int res;
-
-       asm volatile("scall"
-                    : "=r"(sc1)
-                    : "r"(scno), "0"(sc1), "r"(sc2), "r"(sc3)
-                    : "lr", "memory");
-       res = sc1;
-       __syscall_return(int, res);
-}
-
-asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize);
-asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
-                              struct pt_regs *regs);
-asmlinkage int sys_rt_sigreturn(struct pt_regs *regs);
-asmlinkage int sys_pipe(unsigned long __user *filedes);
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
-                         unsigned long prot, unsigned long flags,
-                         unsigned long fd, off_t offset);
-asmlinkage int sys_cacheflush(int operation, void __user *addr, size_t len);
-asmlinkage int sys_fork(struct pt_regs *regs);
-asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
-                        unsigned long parent_tidptr,
-                        unsigned long child_tidptr, struct pt_regs *regs);
-asmlinkage int sys_vfork(struct pt_regs *regs);
-asmlinkage int sys_execve(char __user *ufilename, char __user *__user *uargv,
-                         char __user *__user *uenvp, struct pt_regs *regs);
-
-#endif
 
 /*
  * "Conditional" syscalls
@@ -384,4 +308,6 @@ asmlinkage int sys_execve(char __user *ufilename, char __user *__user *uargv,
  */
 #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall");
 
+#endif /* __KERNEL__ */
+
 #endif /* __ASM_AVR32_UNISTD_H */
index 7372efae05163d166ab1ebec5b94cb7c5b1e0134..7c90fa970c3842f468b88b163943770425db6dbe 100644 (file)
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/linkage.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static inline _syscall0(pid_t,setsid)
-static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
-static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
-static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
-static inline _syscall1(int,dup,int,fd)
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
-static inline _syscall1(int,close,int,fd)
-
-struct pt_regs;
-asmlinkage long sys_mmap2(
-                       unsigned long addr, unsigned long len,
-                       unsigned long prot, unsigned long flags,
-                       unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_execve(const char *fname, char **argv, char **envp,
-                       long r13, long mof, long srp, struct pt_regs *regs);
-asmlinkage int sys_clone(unsigned long newusp, unsigned long flags,
-                       int* parent_tid, int* child_tid, long mof, long srp,
-                       struct pt_regs *regs);
-asmlinkage int sys_fork(long r10, long r11, long r12, long r13,
-                       long mof, long srp, struct pt_regs *regs);
-asmlinkage int sys_vfork(long r10, long r11, long r12, long r13,
-                       long mof, long srp, struct pt_regs *regs);
-asmlinkage int sys_pipe(unsigned long __user *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-                               const struct sigaction __user *act,
-                               struct sigaction __user *oact,
-                               size_t sigsetsize);
-
-/*
- * Since we define it "external", it collides with the built-in
- * definition, which has the "noreturn" attribute and will cause
- * complaints.  We don't want to use -fno-builtin, so just use a
- * different name when in the kernel.
- */
-#define _exit kernel_syscall_exit
-static inline _syscall1(int,_exit,int,exitcode)
-static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-#endif /* __KERNEL_SYSCALLS__ */
-
-
 /*
  * "Conditional" syscalls
  *
index 84ddd6445f23ae6cd5d12aec91552be4a4ef39d0..4ea57171d9516be6964702d0be919950c1145442 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * asm/namei.h
+ * include/asm-frv/namei.h
  *
  * Included from linux/fs/namei.c
  */
index d104d1b91d399bb4f34f627b478f8740ebbee662..725e854928cf3cf60f79863fd2db64011ad0747c 100644 (file)
@@ -440,31 +440,6 @@ type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg
        __syscall_return(type, __sc0);                                                           \
 }
 
-
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/linkage.h>
-#include <asm/ptrace.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 #define __ARCH_WANT_IPC_PARSE_VERSION
 /* #define __ARCH_WANT_OLD_READDIR */
 #define __ARCH_WANT_OLD_STAT
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 a2dd90462d80f172b17760b1501dfd6c91e3030d..747788d629ae1dc192d87356bb15a986dca95e75 100644 (file)
@@ -485,57 +485,6 @@ type name(atype a, btype b, ctype c, dtype d, etype e, ftype f)    \
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static inline _syscall0(int,pause)
-static inline _syscall0(int,sync)
-static inline _syscall0(pid_t,setsid)
-static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
-static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
-static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
-static inline _syscall1(int,dup,int,fd)
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
-static inline _syscall1(int,close,int,fd)
-static inline _syscall1(int,_exit,int,exitcode)
-static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-static inline _syscall1(int,delete_module,const char *,name)
-
-static inline pid_t wait(int * wait_stat)
-{
-       return waitpid(-1,wait_stat,0);
-}
-
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
-                       unsigned long prot, unsigned long flags,
-                       unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_execve(char *name, char **argv, char **envp,
-                       int dummy, ...);
-asmlinkage int sys_pipe(unsigned long *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-                               const struct sigaction __user *act,
-                               struct sigaction __user *oact,
-                               size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  */
index 2a9e4ee5904d50b91d3b6310ed2e78451ce2630c..592ffeeda45e7745c4554201ce8a78da1a80df38 100644 (file)
@@ -189,6 +189,6 @@ static void __init check_bugs(void)
        check_fpu();
        check_hlt();
        check_popad();
-       system_utsname.machine[1] = '0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86);
+       init_utsname()->machine[1] = '0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86);
        alternative_instructions(); 
 }
index db4344d9f73f52fe716076b7f3704a0455f747ae..3a05436f31c0e8252e01389f251d7d5225711583 100644 (file)
@@ -112,7 +112,7 @@ typedef struct user_fxsr_struct elf_fpxregset_t;
    For the moment, we have only optimizations for the Intel generations,
    but that could change... */
 
-#define ELF_PLATFORM  (system_utsname.machine)
+#define ELF_PLATFORM  (utsname()->machine)
 
 #define SET_PERSONALITY(ex, ibcs2) do { } while (0)
 
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 */
index 4b3b526c5a3f64503aceeea46e4eb4e8c7277362..fbb1f3b71279d5da826870b3186e53bd3e463a65 100644 (file)
@@ -181,7 +181,7 @@ static __inline__ void mca_set_dma_io(unsigned int dmanr, unsigned int io_addr)
  *     @mode: mode to set
  *
  *     The DMA controller supports several modes. The mode values you can
- *     set are :
+ *     set are-
  *
  *     %MCA_DMA_MODE_READ when reading from the DMA device.
  *
@@ -190,7 +190,6 @@ static __inline__ void mca_set_dma_io(unsigned int dmanr, unsigned int io_addr)
  *     %MCA_DMA_MODE_IO to do DMA to or from an I/O port.
  *
  *     %MCA_DMA_MODE_16 to do 16bit transfers.
- *
  */
 
 static __inline__ void mca_set_dma_mode(unsigned int dmanr, unsigned int mode)
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 a4a0e5207db58627c4ef02eb1a22eceb54c20a86..d505f501077a67bc77b01729a724b61eb6e26b7a 100644 (file)
@@ -47,7 +47,10 @@ static inline int user_mode_vm(struct pt_regs *regs)
 {
        return ((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= USER_RPL;
 }
+
 #define instruction_pointer(regs) ((regs)->eip)
+#define regs_return_value(regs) ((regs)->eax)
+
 extern unsigned long profile_pc(struct pt_regs *regs);
 #endif /* __KERNEL__ */
 
index 6adbd9b1ae881121e9f377a121ec0c4e9355361c..978d09596130d2625d2eee9be4e8b850e8cbf4c5 100644 (file)
@@ -74,6 +74,7 @@ static inline int node_to_first_cpu(int node)
 #define SD_NODE_INIT (struct sched_domain) {           \
        .span                   = CPU_MASK_NONE,        \
        .parent                 = NULL,                 \
+       .child                  = NULL,                 \
        .groups                 = NULL,                 \
        .min_interval           = 8,                    \
        .max_interval           = 32,                   \
index bd9987087adc6adb90d95daabf67c4eba7be8392..3ca7ab963d7d6ad2f152bd927314e15639223d29 100644 (file)
@@ -451,45 +451,6 @@ __syscall_return(type,__res); \
 #define __ARCH_WANT_SYS_RT_SIGACTION
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/linkage.h>
-#include <asm/ptrace.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-
-asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount);
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
-                       unsigned long prot, unsigned long flags,
-                       unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_execve(struct pt_regs regs);
-asmlinkage int sys_clone(struct pt_regs regs);
-asmlinkage int sys_fork(struct pt_regs regs);
-asmlinkage int sys_vfork(struct pt_regs regs);
-asmlinkage int sys_pipe(unsigned long __user *fildes);
-asmlinkage long sys_iopl(unsigned long unused);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-                               const struct sigaction __user *act,
-                               struct sigaction __user *oact,
-                               size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  *
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 1414316efd405028d84a357a198a7fd3684e8f2a..f4ef87a3623674db5c8510374aeb0b3ecea8d333 100644 (file)
@@ -241,6 +241,9 @@ struct switch_stack {
  * the canonical representation by adding to instruction pointer.
  */
 # define instruction_pointer(regs) ((regs)->cr_iip + ia64_psr(regs)->ri)
+
+#define regs_return_value(regs) ((regs)->r8)
+
 /* Conserve space in histogram by encoding slot bits in address
  * bits 2 and 3 rather than bits 0 and 1.
  */
index 937c212575239f3ec9ee9526e2c989289669f967..a6e38565ab4c068e6adc16738c7418c7b247b3c9 100644 (file)
@@ -59,6 +59,7 @@ void build_cpu_to_node_map(void);
 #define SD_CPU_INIT (struct sched_domain) {            \
        .span                   = CPU_MASK_NONE,        \
        .parent                 = NULL,                 \
+       .child                  = NULL,                 \
        .groups                 = NULL,                 \
        .min_interval           = 1,                    \
        .max_interval           = 4,                    \
@@ -84,6 +85,7 @@ void build_cpu_to_node_map(void);
 #define SD_NODE_INIT (struct sched_domain) {           \
        .span                   = CPU_MASK_NONE,        \
        .parent                 = NULL,                 \
+       .child                  = NULL,                 \
        .groups                 = NULL,                 \
        .min_interval           = 8,                    \
        .max_interval           = 8*(min(num_online_cpus(), 32)), \
index bb0eb727dcd086fb15d43135ca7e0e20ebb4cdf8..53c5c0ee122c96291655807f05dc8a60d121773f 100644 (file)
 
 extern long __ia64_syscall (long a0, long a1, long a2, long a3, long a4, long nr);
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/string.h>
-#include <linux/signal.h>
-#include <asm/ptrace.h>
-#include <linux/stringify.h>
-#include <linux/syscalls.h>
-
-static inline long
-open (const char * name, int mode, int flags)
-{
-       return sys_open(name, mode, flags);
-}
-
-static inline long
-dup (int fd)
-{
-       return sys_dup(fd);
-}
-
-static inline long
-close (int fd)
-{
-       return sys_close(fd);
-}
-
-static inline off_t
-lseek (int fd, off_t off, int whence)
-{
-       return sys_lseek(fd, off, whence);
-}
-
-static inline void
-_exit (int value)
-{
-       sys_exit(value);
-}
-
-#define exit(x) _exit(x)
-
-static inline long
-write (int fd, const char * buf, size_t nr)
-{
-       return sys_write(fd, buf, nr);
-}
-
-static inline long
-read (int fd, char * buf, size_t nr)
-{
-       return sys_read(fd, buf, nr);
-}
-
-
-static inline long
-setsid (void)
-{
-       return sys_setsid();
-}
-
-static inline pid_t
-waitpid (int pid, int * wait_stat, int flags)
-{
-       return sys_wait4(pid, wait_stat, flags, NULL);
-}
-
-
-extern int execve (const char *filename, char *const av[], char *const ep[]);
-extern pid_t clone (unsigned long flags, void *sp);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 asmlinkage unsigned long sys_mmap(
                                unsigned long addr, unsigned long len,
                                int prot, int flags,
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 5c6a9ac6cf1aea11eefcca4969dae98057e6c724..95aa34298d8211d85252976da8931d49f9ef5665 100644 (file)
@@ -424,43 +424,6 @@ __syscall_return(type,__res); \
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_RT_SIGACTION
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/linkage.h>
-#include <asm/ptrace.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-static __inline__ _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
-                         unsigned long prot, unsigned long flags,
-                         unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_execve(struct pt_regs regs);
-asmlinkage int sys_clone(struct pt_regs regs);
-asmlinkage int sys_fork(struct pt_regs regs);
-asmlinkage int sys_vfork(struct pt_regs regs);
-asmlinkage int sys_pipe(unsigned long __user *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-                                const struct sigaction __user *act,
-                                struct sigaction __user *oact,
-                                size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  *
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 751632b904dbca90a4e8a1967ff24a28815d9532..3ab716f0fc18a7870df7a1359fea9df74b16119e 100644 (file)
@@ -409,12 +409,6 @@ __syscall_return(type,__res); \
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 
-#ifdef __KERNEL_SYSCALLS__
-
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  *
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 21fdc37c5c2c60c8c4e69d0a6829efa297042dc9..daafb5d43ef196c6fbc829d78ad0cdf508562c6e 100644 (file)
@@ -463,61 +463,6 @@ type name(atype a, btype b, ctype c, dtype d, etype e)                             \
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/interrupt.h>
-#include <linux/types.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static inline _syscall0(int,pause)
-static inline _syscall0(int,sync)
-static inline _syscall0(pid_t,setsid)
-static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
-static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
-static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
-static inline _syscall1(int,dup,int,fd)
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
-static inline _syscall1(int,close,int,fd)
-static inline _syscall1(int,_exit,int,exitcode)
-static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-static inline _syscall1(int,delete_module,const char *,name)
-
-static inline pid_t wait(int * wait_stat)
-{
-       return waitpid(-1,wait_stat,0);
-}
-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
-                       unsigned long prot, unsigned long flags,
-                       unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_execve(char *name, char **argv, char **envp);
-asmlinkage int sys_pipe(unsigned long *fildes);
-struct pt_regs;
-int sys_request_irq(unsigned int,
-                       irqreturn_t (*)(int, void *, struct pt_regs *),
-                       unsigned long, const char *, void *);
-void sys_free_irq(unsigned int, void *);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-                               const struct sigaction __user *act,
-                               struct sigaction __user *oact,
-                               size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  *
index 78c35ec463624d2c4d337f9dbd2d2c2a25701301..1e5ccdad3b0213db17810f813b649357a147aa17 100644 (file)
 #define  MACH_MOMENCO_JAGUAR_ATX 3
 #define  MACH_MOMENCO_OCELOT_3 4
 
-/*
- * Valid machtype for group ITE
- */
-#define MACH_GROUP_ITE         13      /* ITE Semi Eval Boards         */
-#define  MACH_QED_4N_S01B      0       /* ITE8172 based eval board */
-
 /*
  * Valid machtype for group PHILIPS
  */
 #define  MACH_PHILIPS_VELO     1       /* Velo */
 #define  MACH_PHILIPS_JBS      2       /* JBS */
 
-/*
- * Valid machtype for group Globespan
- */
-#define MACH_GROUP_GLOBESPAN   15      /* Globespan */
-#define  MACH_IVR              0       /* IVR eval board */
-
 /*
  * Valid machtype for group SIBYTE
  */
index 36416fdfcf6893030e4f0325e8407023857babc0..9ab59e2bb23368530fa67c95af0d6ab2c4f7fe8f 100644 (file)
@@ -46,8 +46,6 @@ static inline void flush_dcache_page(struct page *page)
 #define flush_dcache_mmap_lock(mapping)                do { } while (0)
 #define flush_dcache_mmap_unlock(mapping)      do { } while (0)
 
-extern void (*__flush_icache_page)(struct vm_area_struct *vma,
-       struct page *page);
 static inline void flush_icache_page(struct vm_area_struct *vma,
        struct page *page)
 {
diff --git a/include/asm-mips/galileo-boards/ev96100.h b/include/asm-mips/galileo-boards/ev96100.h
deleted file mode 100644 (file)
index 070dfd8..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *
- */
-#ifndef _MIPS_EV96100_H
-#define _MIPS_EV96100_H
-
-#include <asm/addrspace.h>
-
-/*
- *   GT64120 config space base address
- */
-#define GT64120_BASE   (KSEG1ADDR(0x14000000))
-#define MIPS_GT_BASE   GT64120_BASE
-
-/*
- *   PCI Bus allocation
- */
-#define GT_PCI_MEM_BASE    0x12000000UL
-#define GT_PCI_MEM_SIZE    0x02000000UL
-#define GT_PCI_IO_BASE     0x10000000UL
-#define GT_PCI_IO_SIZE     0x02000000UL
-#define GT_ISA_IO_BASE     PCI_IO_BASE
-
-/*
- *   Duart I/O ports.
- */
-#define EV96100_COM1_BASE_ADDR         (0xBD000000 + 0x20)
-#define EV96100_COM2_BASE_ADDR (0xBD000000 + 0x00)
-
-
-/*
- *   EV96100 interrupt controller register base.
- */
-#define EV96100_ICTRL_REGS_BASE        (KSEG1ADDR(0x1f000000))
-
-/*
- *   EV96100 UART register base.
- */
-#define EV96100_UART0_REGS_BASE        EV96100_COM1_BASE_ADDR
-#define EV96100_UART1_REGS_BASE        EV96100_COM2_BASE_ADDR
-#define EV96100_BASE_BAUD      ( 3686400 / 16 )
-
-
-/*
- * Because of an error/peculiarity in the Galileo chip, we need to swap the
- * bytes when running bigendian.
- */
-#define __GT_READ(ofs)                                                 \
-       (*(volatile u32 *)(GT64120_BASE+(ofs)))
-#define __GT_WRITE(ofs, data)                                          \
-       do { *(volatile u32 *)(GT64120_BASE+(ofs)) = (data); } while (0)
-#define GT_READ(ofs)           le32_to_cpu(__GT_READ(ofs))
-#define GT_WRITE(ofs, data)    __GT_WRITE(ofs, cpu_to_le32(data))
-
-#endif /* !(_MIPS_EV96100_H) */
diff --git a/include/asm-mips/galileo-boards/ev96100int.h b/include/asm-mips/galileo-boards/ev96100int.h
deleted file mode 100644 (file)
index c58b16d..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- *
- */
-#ifndef _MIPS_EV96100INT_H
-#define _MIPS_EV96100INT_H
-
-#define EV96100INT_UART_0    6     /* IP 6 */
-#define EV96100INT_TIMER     7     /* IP 7 */
-
-extern void ev96100int_init(void);
-
-#endif /* !(_MIPS_EV96100_H) */
index 43ca09a3a3d0ca2735b6f0b364c0190cee2569c4..46bf5de5ac720f1691b75bce5ea022eb7cf7d874 100644 (file)
@@ -213,12 +213,37 @@ static inline int raw_irqs_disabled_flags(unsigned long flags)
  * Do the CPU's IRQ-state tracing from assembly code.
  */
 #ifdef CONFIG_TRACE_IRQFLAGS
+/* Reload some registers clobbered by trace_hardirqs_on */
+#ifdef CONFIG_64BIT
+# define TRACE_IRQS_RELOAD_REGS                                                \
+       LONG_L  $11, PT_R11(sp);                                        \
+       LONG_L  $10, PT_R10(sp);                                        \
+       LONG_L  $9, PT_R9(sp);                                          \
+       LONG_L  $8, PT_R8(sp);                                          \
+       LONG_L  $7, PT_R7(sp);                                          \
+       LONG_L  $6, PT_R6(sp);                                          \
+       LONG_L  $5, PT_R5(sp);                                          \
+       LONG_L  $4, PT_R4(sp);                                          \
+       LONG_L  $2, PT_R2(sp)
+#else
+# define TRACE_IRQS_RELOAD_REGS                                                \
+       LONG_L  $7, PT_R7(sp);                                          \
+       LONG_L  $6, PT_R6(sp);                                          \
+       LONG_L  $5, PT_R5(sp);                                          \
+       LONG_L  $4, PT_R4(sp);                                          \
+       LONG_L  $2, PT_R2(sp)
+#endif
 # define TRACE_IRQS_ON                                                 \
+       CLI;    /* make sure trace_hardirqs_on() is called in kernel level */ \
        jal     trace_hardirqs_on
+# define TRACE_IRQS_ON_RELOAD                                          \
+       TRACE_IRQS_ON;                                                  \
+       TRACE_IRQS_RELOAD_REGS
 # define TRACE_IRQS_OFF                                                        \
        jal     trace_hardirqs_off
 #else
 # define TRACE_IRQS_ON
+# define TRACE_IRQS_ON_RELOAD
 # define TRACE_IRQS_OFF
 #endif
 
diff --git a/include/asm-mips/it8172/it8172.h b/include/asm-mips/it8172/it8172.h
deleted file mode 100644 (file)
index 8f23af0..0000000
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *     IT8172 system controller defines.
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@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.
- */
-
-#ifndef __IT8172__H__
-#define __IT8172__H__
-
-#include <asm/addrspace.h>
-
-#define IT8172_BASE                    0x18000000
-#define IT8172_PCI_IO_BASE             0x14000000
-#define IT8172_PCI_MEM_BASE            0x10000000
-
-// System registers offsets from IT8172_BASE
-#define IT_CMFPCR                      0x0
-#define IT_DSRR                                0x2
-#define IT_PCDCR                       0x4
-#define IT_SPLLCR                      0x6
-#define IT_CIDR                                0x10
-#define IT_CRNR                                0x12
-#define IT_CPUTR                       0x14
-#define IT_CTCR                                0x16
-#define IT_SDPR                                0xF0
-
-// Power management register offset from IT8172_PCI_IO_BASE
-// Power Management Device Standby Register
-#define IT_PM_DSR              0x15800
-
-#define IT_PM_DSR_TMR0SB       0x0001
-#define IT_PM_DSR_TMR1SB       0x0002
-#define IT_PM_DSR_CIR0SB       0x0004
-#define IT_PM_DSR_CIR1SB       0x0008
-#define IT_PM_DSR_SCR0SB       0x0010
-#define IT_PM_DSR_SCR1SB       0x0020
-#define IT_PM_DSR_PPSB         0x0040
-#define IT_PM_DSR_I2CSB                0x0080
-#define IT_PM_DSR_UARTSB       0x0100
-#define IT_PM_DSR_IDESB                0x0200
-#define IT_PM_DSR_ACSB         0x0400
-#define IT_PM_DSR_M68KSB       0x0800
-
-// Power Management PCI Device Software Reset Register
-#define IT_PM_PCISR             0x15802
-
-#define IT_PM_PCISR_IDESR       0x0001
-#define IT_PM_PCISR_CDMASR      0x0002
-#define IT_PM_PCISR_USBSR       0x0004
-#define IT_PM_PCISR_DMASR       0x0008
-#define IT_PM_PCISR_ACSR        0x0010
-#define IT_PM_PCISR_MEMSR       0x0020
-#define IT_PM_PCISR_68KSR       0x0040
-
-
-// PCI Configuration address and data register offsets
-// from IT8172_BASE
-#define IT_CONFADDR                    0x4000
-#define IT_BUSNUM_SHF                   16
-#define IT_DEVNUM_SHF                   11
-#define IT_FUNCNUM_SHF                  8
-#define IT_REGNUM_SHF                   2
-
-#define IT_CONFDATA                    0x4004
-
-// PCI configuration header common register offsets
-#define IT_VID                         0x00
-#define IT_DID                         0x02
-#define IT_PCICMD                      0x04
-#define IT_PCISTS                      0x06
-#define IT_RID                         0x08
-#define IT_CLASSC                      0x09
-#define IT_HEADT                       0x0E
-#define IT_SERIRQC                     0x49
-
-// PCI to Internal/LPC Bus Bridge configuration header register offset
-#define IT_P2I_BCR                             0x4C
-#define IT_P2I_D0IOSC                          0x50
-#define IT_P2I_D1IOSC                          0x54
-#define IT_P2I_D2IOSC                          0x58
-#define IT_P2I_D3IOSC                          0x5C
-#define IT_P2I_D4IOSC                          0x60
-#define IT_P2I_D5IOSC                          0x64
-#define IT_P2I_D6IOSC                          0x68
-#define IT_P2I_D7IOSC                          0x6C
-#define IT_P2I_D8IOSC                          0x70
-#define IT_P2I_D9IOSC                          0x74
-#define IT_P2I_D10IOSC                         0x78
-#define IT_P2I_D11IOSC                         0x7C
-
-// Memory controller register offsets from IT8172_BASE
-#define IT_MC_SDRMR                                    0x1000
-#define IT_MC_SDRTR                                    0x1004
-#define IT_MC_MCR                                      0x1008
-#define IT_MC_SDTYPE                                   0x100C
-#define IT_MC_WPBA                                     0x1010
-#define IT_MC_WPTA                                     0x1014
-#define IT_MC_HATR                                     0x1018
-#define IT_MC_PCICR                                    0x101C
-
-// Flash/ROM control register offsets from IT8172_BASE
-#define IT_FC_BRCR                                     0x2000
-#define IT_FC_FCR                                      0x2004
-#define IT_FC_DCR                                      0x2008
-
-// M68K interface bridge configuration header register offset
-#define IT_M68K_MBCSR                                  0x54
-#define IT_M68K_TMR                                    0x58
-#define IT_M68K_BCR                                    0x5C
-#define IT_M68K_BSR                                    0x5D
-#define IT_M68K_DTR                                    0x5F
-
-// Register offset from IT8172_PCI_IO_BASE
-// These registers are accessible through 8172 PCI IO window.
-
-// INTC
-#define IT_INTC_BASE                           0x10000
-#define IT_INTC_LBDNIRR                                0x10000
-#define IT_INTC_LBDNIMR                                0x10002
-#define IT_INTC_LBDNITR                                0x10004
-#define IT_INTC_LBDNIAR                                0x10006
-#define IT_INTC_LPCNIRR                                0x10010
-#define IT_INTC_LPCNIMR                                0x10012
-#define IT_INTC_LPCNITR                                0x10014
-#define IT_INTC_LPCNIAR                                0x10016
-#define IT_INTC_PDNIRR                         0x10020
-#define IT_INTC_PDNIMR                         0x10022
-#define IT_INTC_PDNITR                         0x10024
-#define IT_INTC_PDNIAR                         0x10026
-#define IT_INTC_UMNIRR                         0x10030
-#define IT_INTC_UMNITR                         0x10034
-#define IT_INTC_UMNIAR                         0x10036
-#define IT_INTC_TYPER                          0x107FE
-
-// IT8172 PCI device number
-#define IT_C2P_DEVICE                          0
-#define IT_AUDIO_DEVICE                                1
-#define IT_DMAC_DEVICE                         1
-#define IT_CDMAC_DEVICE                                1
-#define IT_USB_DEVICE                          1
-#define IT_P2I_DEVICE                          1
-#define IT_IDE_DEVICE                          1
-#define IT_M68K_DEVICE                         1
-
-// IT8172 PCI function number
-#define IT_C2P_FUNCION                         0
-#define IT_AUDIO_FUNCTION                      0
-#define IT_DMAC_FUNCTION                       1
-#define IT_CDMAC_FUNCTION                      2
-#define IT_USB_FUNCTION                                3
-#define IT_P2I_FUNCTION                                4
-#define IT_IDE_FUNCTION                                5
-#define IT_M68K_FUNCTION                       6
-
-// IT8172 GPIO
-#define IT_GPADR                               0x13800
-#define IT_GPBDR                               0x13808
-#define IT_GPCDR                               0x13810
-#define IT_GPACR                               0x13802
-#define IT_GPBCR                               0x1380A
-#define IT_GPCCR                               0x13812
-#define IT_GPAICR                              0x13804
-#define IT_GPBICR                              0x1380C
-#define IT_GPCICR                              0x13814
-#define IT_GPAISR                              0x13806
-#define IT_GPBISR                              0x1380E
-#define IT_GPCISR                              0x13816
-#define IT_GCR                                 0x13818
-
-// IT8172 RTC
-#define IT_RTC_BASE                            0x14800
-#define IT_RTC_CENTURY                         0x14808
-
-#define IT_RTC_RIR0                            0x00
-#define IT_RTC_RTR0                            0x01
-#define IT_RTC_RIR1                            0x02
-#define IT_RTC_RTR1                            0x03
-#define IT_RTC_RIR2                            0x04
-#define IT_RTC_RTR2                            0x05
-#define IT_RTC_RCTR                            0x08
-#define IT_RTC_RA                              0x0A
-#define IT_RTC_RB                              0x0B
-#define IT_RTC_RC                              0x0C
-#define IT_RTC_RD                              0x0D
-
-#define RTC_SEC_INDEX                          0x00
-#define RTC_MIN_INDEX                          0x02
-#define RTC_HOUR_INDEX                         0x04
-#define RTC_DAY_INDEX                          0x06
-#define RTC_DATE_INDEX                         0x07
-#define RTC_MONTH_INDEX                                0x08
-#define RTC_YEAR_INDEX                         0x09
-
-// IT8172 internal device registers
-#define IT_TIMER_BASE                          0x10800
-#define IT_CIR0_BASE                           0x11000
-#define IT_UART_BASE                           0x11800
-#define IT_SCR0_BASE                           0x12000
-#define IT_SCR1_BASE                           0x12800
-#define IT_PP_BASE                             0x13000
-#define IT_I2C_BASE                            0x14000
-#define IT_CIR1_BASE                           0x15000
-
-// IT8172 Smart Card Reader offsets from IT_SCR*_BASE
-#define IT_SCR_SFR                             0x08
-#define IT_SCR_SCDR                            0x09
-
-// IT8172 IT_SCR_SFR bit definition & mask
-#define        IT_SCR_SFR_GATE_UART                    0x40
-#define        IT_SCR_SFR_GATE_UART_BIT                6
-#define IT_SCR_SFR_GATE_UART_OFF               0
-#define        IT_SCR_SFR_GATE_UART_ON                 1
-#define        IT_SCR_SFR_FET_CHARGE                   0x30
-#define        IT_SCR_SFR_FET_CHARGE_BIT               4
-#define IT_SCR_SFR_FET_CHARGE_3_3_US           3
-#define IT_SCR_SFR_FET_CHARGE_13_US            2
-#define IT_SCR_SFR_FET_CHARGE_53_US            1
-#define IT_SCR_SFR_FET_CHARGE_213_US           0
-#define        IT_SCR_SFR_CARD_FREQ                    0x0C
-#define        IT_SCR_SFR_CARD_FREQ_BIT                2
-#define IT_SCR_SFR_CARD_FREQ_STOP              3
-#define IT_SCR_SFR_CARD_FREQ_3_5_MHZ           0
-#define IT_SCR_SFR_CARD_FREQ_7_1_MHZ           2
-#define IT_SCR_SFR_CARD_FREQ_96_DIV_MHZ                1
-#define        IT_SCR_SFR_FET_ACTIVE                   0x02
-#define        IT_SCR_SFR_FET_ACTIVE_BIT               1
-#define IT_SCR_SFR_FET_ACTIVE_INVERT           0
-#define IT_SCR_SFR_FET_ACTIVE_NONINVERT                1
-#define        IT_SCR_SFR_ENABLE                       0x01
-#define        IT_SCR_SFR_ENABLE_BIT                   0
-#define IT_SCR_SFR_ENABLE_OFF                  0
-#define IT_SCR_SFR_ENABLE_ON                   1
-
-// IT8172 IT_SCR_SCDR bit definition & mask
-#define        IT_SCR_SCDR_RESET_MODE                  0x80
-#define        IT_SCR_SCDR_RESET_MODE_BIT              7
-#define        IT_SCR_SCDR_RESET_MODE_ASYNC            0
-#define IT_SCR_SCDR_RESET_MODE_SYNC            1
-#define        IT_SCR_SCDR_DIVISOR                     0x7F
-#define        IT_SCR_SCDR_DIVISOR_BIT                 0
-#define        IT_SCR_SCDR_DIVISOR_STOP_VAL_1          0x00
-#define        IT_SCR_SCDR_DIVISOR_STOP_VAL_2          0x01
-#define        IT_SCR_SCDR_DIVISOR_STOP_VAL_3          0x7F
-
-// IT8172 DMA
-#define IT_DMAC_BASE                           0x16000
-#define IT_DMAC_BCAR0                          0x00
-#define IT_DMAC_BCAR1                          0x04
-#define IT_DMAC_BCAR2                          0x08
-#define IT_DMAC_BCAR3                          0x0C
-#define IT_DMAC_BCCR0                          0x02
-#define IT_DMAC_BCCR1                          0x06
-#define IT_DMAC_BCCR2                          0x0a
-#define IT_DMAC_BCCR3                          0x0e
-#define IT_DMAC_CR                             0x10
-#define IT_DMAC_SR                             0x12
-#define IT_DMAC_ESR                            0x13
-#define IT_DMAC_RQR                            0x14
-#define IT_DMAC_MR                             0x16
-#define IT_DMAC_EMR                            0x17
-#define IT_DMAC_MKR                            0x18
-#define IT_DMAC_PAR0                           0x20
-#define IT_DMAC_PAR1                           0x22
-#define IT_DMAC_PAR2                           0x24
-#define IT_DMAC_PAR3                           0x26
-
-// IT8172 IDE
-#define IT_IDE_BASE                            0x17800
-#define IT_IDE_STATUS                          0x1F7
-
-// IT8172 Audio Controller
-#define IT_AC_BASE                             0x17000
-#define        IT_AC_PCMOV                             0x00
-#define IT_AC_FMOV                             0x02
-#define        IT_AC_I2SV                              0x04
-#define IT_AC_DRSS                             0x06
-#define IT_AC_PCC                              0x08
-#define IT_AC_PCDL                             0x0A
-#define IT_AC_PCB1STA                          0x0C
-#define IT_AC_PCB2STA                          0x10
-#define IT_AC_CAPCC                            0x14
-#define IT_AC_CAPCDL                           0x16
-#define IT_AC_CAPB1STA                         0x18
-#define IT_AC_CAPB2STA                         0x1C
-#define IT_AC_CODECC                           0x22
-#define IT_AC_I2SMC                            0x24
-#define IT_AC_VS                               0x26
-#define IT_AC_SRCS                             0x28
-#define IT_AC_CIRCP                            0x2A
-#define IT_AC_CIRDP                            0x2C
-#define IT_AC_TM                               0x4A
-#define IT_AC_PFDP                             0x4C
-#define IT_AC_GC                               0x54
-#define IT_AC_IMC                              0x56
-#define IT_AC_ISC                              0x5B
-#define IT_AC_OPL3SR                           0x68
-#define IT_AC_OPL3DWDR                         0x69
-#define IT_AC_OPL3AB1W                         0x6A
-#define IT_AC_OPL3DW                           0x6B
-#define IT_AC_BPDC                             0x70
-
-
-// IT8172 Timer
-#define IT_TIMER_BASE                          0x10800
-#define        TIMER_TCVR0                             0x00
-#define TIMER_TRVR0                            0x02
-#define        TIMER_TCR0                              0x04
-#define TIMER_TIRR                             0x06
-#define        TIMER_TCVR1                             0x08
-#define TIMER_TRVR1                            0x0A
-#define        TIMER_TCR1                              0x0C
-#define TIMER_TIDR                             0x0E
-
-
-#define IT_WRITE(ofs, data) *(volatile u32 *)KSEG1ADDR((IT8172_BASE+ofs)) = data
-#define IT_READ(ofs, data)  data = *(volatile u32 *)KSEG1ADDR((IT8172_BASE+ofs))
-
-#define IT_IO_WRITE(ofs, data) *(volatile u32 *)KSEG1ADDR((IT8172_PCI_IO_BASE+ofs)) = data
-#define IT_IO_READ(ofs, data)  data = *(volatile u32 *)KSEG1ADDR((IT8172_PCI_IO_BASE+ofs))
-
-#define IT_IO_WRITE16(ofs, data) *(volatile u16 *)KSEG1ADDR((IT8172_PCI_IO_BASE+ofs)) = data
-#define IT_IO_READ16(ofs, data)  data = *(volatile u16 *)KSEG1ADDR((IT8172_PCI_IO_BASE+ofs))
-
-#endif
diff --git a/include/asm-mips/it8172/it8172_cir.h b/include/asm-mips/it8172/it8172_cir.h
deleted file mode 100644 (file)
index 6a1dbd2..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *     IT8172 Consumer IR port defines.
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@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.
- */
-
-#define NUM_CIR_PORTS 2
-
-/* Master Control Register */
-#define CIR_RESET              0x1
-#define CIR_FIFO_CLEAR         0x2
-#define CIR_SET_FIFO_TL(x)     (((x)&0x3)<<2)
-#define CIR_ILE                0x10
-#define CIR_ILSEL              0x20
-
-/* Interrupt Enable Register */
-#define CIR_TLDLIE             0x1
-#define CIR_RDAIE              0x2
-#define CIR_RFOIE              0x4
-#define CIR_IEC                0x80
-
-/* Interrupt Identification Register */
-#define CIR_TLDLI              0x1
-#define CIR_RDAI               0x2
-#define CIR_RFOI               0x4
-#define CIR_NIP                0x80
-
-/* Carrier Frequency Register */
-#define CIR_SET_CF(x)          ((x)&0x1f)
-  #define CFQ_38_480           0xB       /* 38 KHz low, 480 KHz high */
-#define CIR_HCFS               0x20
-  #define CIR_SET_HS(x)        (((x)&0x1)<<5)
-
-
-/* Receiver Control Register */
-#define CIR_SET_RXDCR(x)       ((x)&0x7)
-#define CIR_RXACT              0x8
-#define CIR_RXEND              0x10
-#define CIR_RDWOS              0x20
-  #define CIR_SET_RDWOS(x)     (((x)&0x1)<<5)
-#define CIR_RXEN               0x80
-
-/* Transmitter Control Register */
-#define CIR_SET_TXMPW(x)       ((x)&0x7)
-#define CIR_SET_TXMPM(x)       (((x)&0x3)<<3)
-#define CIR_TXENDF             0x20
-#define CIR_TXRLE              0x40
-
-/* Receiver FIFO Status Register */
-#define CIR_RXFBC_MASK         0x3f
-#define CIR_RXFTO              0x80
-
-/* Wakeup Code Length Register */
-#define CIR_SET_WCL            ((x)&0x3f)
-#define CIR_WCL_MASK(x)        ((x)&0x3f)
-
-/* Wakeup Power Control/Status Register */
-#define CIR_BTMON              0x2
-#define CIR_CIRON              0x4
-#define CIR_RCRST              0x10
-#define CIR_WCRST              0x20
-
-struct cir_port {
-       int port;
-       unsigned short baud_rate;
-       unsigned char fifo_tl;
-       unsigned char cfq;
-       unsigned char hcfs;
-       unsigned char rdwos;
-       unsigned char rxdcr;
-};
-
-struct it8172_cir_regs {
-       unsigned char dr;       /* data                        */
-       char pad;
-       unsigned char mstcr;    /* master control              */
-       char pad1;
-       unsigned char ier;      /* interrupt enable            */
-       char pad2;
-       unsigned char iir;      /* interrupt identification    */
-       char pad3;
-       unsigned char cfr;      /* carrier frequency           */
-       char pad4;
-       unsigned char rcr;      /* receiver control            */
-       char pad5;
-       unsigned char tcr;      /* transmitter control         */
-       char pad6;
-       char pad7;
-       char pad8;
-       unsigned char bdlr;     /* baud rate divisor low byte  */
-       char pad9;
-       unsigned char bdhr;     /* baud rate divisor high byte */
-       char pad10;
-       unsigned char tfsr;     /* tx fifo byte count          */
-       char pad11;
-       unsigned char rfsr;     /* rx fifo status              */
-       char pad12;
-       unsigned char wcl;      /* wakeup code length          */
-       char pad13;
-       unsigned char wcr;      /* wakeup code read/write      */
-       char pad14;
-       unsigned char wps;      /* wakeup power control/status */
-};
-
-int cir_port_init(struct cir_port *cir);
-extern void clear_fifo(struct cir_port *cir);
-extern void enable_receiver(struct cir_port *cir);
-extern void disable_receiver(struct cir_port *cir);
-extern void enable_rx_demodulation(struct cir_port *cir);
-extern void disable_rx_demodulation(struct cir_port *cir);
-extern void set_rx_active(struct cir_port *cir);
-extern void int_enable(struct cir_port *cir);
-extern void rx_int_enable(struct cir_port *cir);
-extern char get_int_status(struct cir_port *cir);
-extern int cir_get_rx_count(struct cir_port *cir);
-extern char cir_read_data(struct cir_port *cir);
diff --git a/include/asm-mips/it8172/it8172_dbg.h b/include/asm-mips/it8172/it8172_dbg.h
deleted file mode 100644 (file)
index f404ec7..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *     Function prototypes for low level uart routines to
- *     directly access a 16550 uart.
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@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.
- */
-
-#include <linux/types.h>
-
-extern void putch(const unsigned char c);
-extern void puts(unsigned char *cp);
-extern void fputs(unsigned char *cp);
-extern void put64(uint64_t ul);
-extern void put32(unsigned u);
diff --git a/include/asm-mips/it8172/it8172_int.h b/include/asm-mips/it8172/it8172_int.h
deleted file mode 100644 (file)
index 837e83a..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *     ITE 8172 Interrupt Numbering
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@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.
- */
-
-#ifndef _MIPS_ITEINT_H
-#define _MIPS_ITEINT_H
-
-/*
- * Here's the "strategy":
- * We number the LPC serial irqs from 0 to 15,
- * the local bus irqs from 16 to 31,
- * the pci dev register interrupts from 32 to 47,
- * and the non-maskable ints from 48 to 53.
- */
-
-#define IT8172_LPC_IRQ_BASE  0    /* first LPC int number */
-#define IT8172_SERIRQ_0      (IT8172_LPC_IRQ_BASE + 0)
-#define IT8172_SERIRQ_1      (IT8172_LPC_IRQ_BASE + 1)
-#define IT8172_SERIRQ_2      (IT8172_LPC_IRQ_BASE + 2)
-#define IT8172_SERIRQ_3      (IT8172_LPC_IRQ_BASE + 3)
-#define IT8172_SERIRQ_4      (IT8172_LPC_IRQ_BASE + 4)
-#define IT8172_SERIRQ_5      (IT8172_LPC_IRQ_BASE + 5)
-#define IT8172_SERIRQ_6      (IT8172_LPC_IRQ_BASE + 6)
-#define IT8172_SERIRQ_7      (IT8172_LPC_IRQ_BASE + 7)
-#define IT8172_SERIRQ_8      (IT8172_LPC_IRQ_BASE + 8)
-#define IT8172_SERIRQ_9      (IT8172_LPC_IRQ_BASE + 9)
-#define IT8172_SERIRQ_10     (IT8172_LPC_IRQ_BASE + 10)
-#define IT8172_SERIRQ_11     (IT8172_LPC_IRQ_BASE + 11)
-#define IT8172_SERIRQ_12     (IT8172_LPC_IRQ_BASE + 12)
-#define IT8172_SERIRQ_13     (IT8172_LPC_IRQ_BASE + 13)
-#define IT8172_SERIRQ_14     (IT8172_LPC_IRQ_BASE + 14)
-#define IT8172_SERIRQ_15     (IT8172_LPC_IRQ_BASE + 15)
-
-#define IT8172_LB_IRQ_BASE  16   /* first local bus int number */
-#define IT8172_PPR_IRQ          (IT8172_LB_IRQ_BASE + 0) /* parallel port */
-#define IT8172_TIMER0_IRQ       (IT8172_LB_IRQ_BASE + 1)
-#define IT8172_TIMER1_IRQ       (IT8172_LB_IRQ_BASE + 2)
-#define IT8172_I2C_IRQ          (IT8172_LB_IRQ_BASE + 3)
-#define IT8172_GPIO_IRQ         (IT8172_LB_IRQ_BASE + 4)
-#define IT8172_CIR0_IRQ         (IT8172_LB_IRQ_BASE + 5)
-#define IT8172_CIR1_IRQ         (IT8172_LB_IRQ_BASE + 6)
-#define IT8172_UART_IRQ         (IT8172_LB_IRQ_BASE + 7)
-#define IT8172_SCR0_IRQ         (IT8172_LB_IRQ_BASE + 8)
-#define IT8172_SCR1_IRQ         (IT8172_LB_IRQ_BASE + 9)
-#define IT8172_RTC_IRQ          (IT8172_LB_IRQ_BASE + 10)
-#define IT8172_IOCHK_IRQ        (IT8172_LB_IRQ_BASE + 11)
-/* 12 - 15 reserved */
-
-/*
- * Note here that the pci dev registers includes bits for more than
- * just the pci devices.
- */
-#define IT8172_PCI_DEV_IRQ_BASE  32   /* first pci dev irq */
-#define IT8172_AC97_IRQ          (IT8172_PCI_DEV_IRQ_BASE + 0)
-#define IT8172_MC68K_IRQ         (IT8172_PCI_DEV_IRQ_BASE + 1)
-#define IT8172_IDE_IRQ           (IT8172_PCI_DEV_IRQ_BASE + 2)
-#define IT8172_USB_IRQ           (IT8172_PCI_DEV_IRQ_BASE + 3)
-#define IT8172_BRIDGE_MASTER_IRQ (IT8172_PCI_DEV_IRQ_BASE + 4)
-#define IT8172_BRIDGE_TARGET_IRQ (IT8172_PCI_DEV_IRQ_BASE + 5)
-#define IT8172_PCI_INTA_IRQ      (IT8172_PCI_DEV_IRQ_BASE + 6)
-#define IT8172_PCI_INTB_IRQ      (IT8172_PCI_DEV_IRQ_BASE + 7)
-#define IT8172_PCI_INTC_IRQ      (IT8172_PCI_DEV_IRQ_BASE + 8)
-#define IT8172_PCI_INTD_IRQ      (IT8172_PCI_DEV_IRQ_BASE + 9)
-#define IT8172_S_INTA_IRQ        (IT8172_PCI_DEV_IRQ_BASE + 10)
-#define IT8172_S_INTB_IRQ        (IT8172_PCI_DEV_IRQ_BASE + 11)
-#define IT8172_S_INTC_IRQ        (IT8172_PCI_DEV_IRQ_BASE + 12)
-#define IT8172_S_INTD_IRQ        (IT8172_PCI_DEV_IRQ_BASE + 13)
-#define IT8172_CDMA_IRQ          (IT8172_PCI_DEV_IRQ_BASE + 14)
-#define IT8172_DMA_IRQ           (IT8172_PCI_DEV_IRQ_BASE + 15)
-
-#define IT8172_NMI_IRQ_BASE      48
-#define IT8172_SER_NMI_IRQ       (IT8172_NMI_IRQ_BASE + 0)
-#define IT8172_PCI_NMI_IRQ       (IT8172_NMI_IRQ_BASE + 1)
-#define IT8172_RTC_NMI_IRQ       (IT8172_NMI_IRQ_BASE + 2)
-#define IT8172_CPUIF_NMI_IRQ     (IT8172_NMI_IRQ_BASE + 3)
-#define IT8172_PMER_NMI_IRQ      (IT8172_NMI_IRQ_BASE + 4)
-#define IT8172_POWER_NMI_IRQ     (IT8172_NMI_IRQ_BASE + 5)
-
-#define IT8172_LAST_IRQ          (IT8172_POWER_NMI_IRQ)
-/* Finally, let's move over here the mips cpu timer interrupt.
- */
-#define MIPS_CPU_TIMER_IRQ       (NR_IRQS-1)
-
-/*
- * IT8172 Interrupt Controller Registers
- */
-struct it8172_intc_regs {
-        volatile unsigned short lb_req;      /* offset 0 */
-        volatile unsigned short lb_mask;
-        volatile unsigned short lb_trigger;
-        volatile unsigned short lb_level;
-       unsigned char pad0[8];
-
-        volatile unsigned short lpc_req;     /* offset 0x10 */
-        volatile unsigned short lpc_mask;
-        volatile unsigned short lpc_trigger;
-        volatile unsigned short lpc_level;
-       unsigned char pad1[8];
-
-        volatile unsigned short pci_req;     /* offset 0x20 */
-        volatile unsigned short pci_mask;
-        volatile unsigned short pci_trigger;
-        volatile unsigned short pci_level;
-       unsigned char pad2[8];
-
-        volatile unsigned short nmi_req;     /* offset 0x30 */
-        volatile unsigned short nmi_mask;
-        volatile unsigned short nmi_trigger;
-        volatile unsigned short nmi_level;
-       unsigned char pad3[6];
-
-        volatile unsigned short nmi_redir;   /* offset 0x3E */
-       unsigned char pad4[0xBE];
-
-        volatile unsigned short intstatus;    /* offset 0xFE */
-};
-
-#endif /* _MIPS_ITEINT_H */
diff --git a/include/asm-mips/it8172/it8172_pci.h b/include/asm-mips/it8172/it8172_pci.h
deleted file mode 100644 (file)
index 42c61f5..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *     IT8172 system controller specific pci defines.
- *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@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.
- */
-
-#ifndef _8172PCI_H_
-#define _8172PCI_H_
-
-// PCI configuration space Type0
-#define        PCI_IDREG       0x00
-#define        PCI_CMDSTSREG   0x04
-#define        PCI_CLASSREG    0x08
-#define        PCI_BHLCREG     0x0C
-#define        PCI_BASE1REG    0x10
-#define        PCI_BASE2REG    0x14
-#define        PCI_BASE3REG    0x18
-#define        PCI_BASE4REG    0x1C
-#define        PCI_BASE5REG    0x20
-#define        PCI_BASE6REG    0x24
-#define        PCI_ROMBASEREG  0x30
-#define        PCI_INTRREG     0x3C
-
-// PCI configuration space Type1
-#define        PCI_BUSNOREG    0x18
-
-#define        IT_PCI_VENDORID(x)      ((x) & 0xFFFF)
-#define        IT_PCI_DEVICEID(x)      (((x)>>16) & 0xFFFF)
-
-// Command register
-#define        PCI_CMD_IOEN            0x00000001
-#define        PCI_CMD_MEMEN           0x00000002
-#define        PCI_CMD_BUSMASTER       0x00000004
-#define        PCI_CMD_SPCYCLE         0x00000008
-#define        PCI_CMD_WRINV           0x00000010
-#define        PCI_CMD_VGASNOOP        0x00000020
-#define        PCI_CMD_PERR            0x00000040
-#define        PCI_CMD_WAITCTRL        0x00000080
-#define        PCI_CMD_SERR            0x00000100
-#define        PCI_CMD_FAST_BACKTOBACK 0x00000200
-
-// Status register
-#define        PCI_STS_66MHZ           0x00200000
-#define        PCI_STS_SUPPORT_UDF     0x00400000
-#define        PCI_STS_FAST_BACKTOBACK 0x00800000
-#define        PCI_STS_DATA_PERR       0x01000000
-#define        PCI_STS_DEVSEL0         0x02000000
-#define        PCI_STS_DEVSEL1         0x04000000
-#define        PCI_STS_SIG_TGTABORT    0x08000000
-#define        PCI_STS_RCV_TGTABORT    0x10000000
-#define        PCI_STS_RCV_MSTABORT    0x20000000
-#define        PCI_STS_SYSERR          0x40000000
-#define        PCI_STS_DETCT_PERR      0x80000000
-
-#define        IT_PCI_CLASS(x)         (((x)>>24) & 0xFF)
-#define        IT_PCI_SUBCLASS(x)              (((x)>>16) & 0xFF)
-#define        IT_PCI_INTERFACE(x)     (((x)>>8) & 0xFF)
-#define        IT_PCI_REVISION(x)              ((x) & 0xFF)
-
-// PCI class code
-#define        PCI_CLASS_BRIDGE                        0x06
-
-// bridge subclass
-#define        PCI_SUBCLASS_BRIDGE_HOST                0x00
-#define        PCI_SUBCLASS_BRIDGE_PCI                 0x04
-
-// BHLCREG
-#define        IT_PCI_BIST(x)          (((x)>>24) & 0xFF)
-#define        IT_PCI_HEADERTYPE(x)    (((x)>>16) & 0xFF)
-#define        IT_PCI_LATENCYTIMER(x)  (((x)>>8) & 0xFF)
-#define        IT_PCI_CACHELINESIZE(x) ((x) & 0xFF)
-
-#define        PCI_MULTIFUNC   0x80
-
-// INTRREG
-#define        IT_PCI_MAXLAT(x)                (((x)>>24) & 0xFF)
-#define        IT_PCI_MINGNT(x)                (((x)>>16) & 0xFF)
-#define        IT_PCI_INTRPIN(x)               (((x)>>8) & 0xFF)
-#define        IT_PCI_INTRLINE(x)              ((x) & 0xFF)
-
-#define        PCI_VENDOR_NEC  0x1033
-#define PCI_VENDOR_DEC 0x1101
-
-#endif // _8172PCI_H_
diff --git a/include/asm-mips/it8712.h b/include/asm-mips/it8712.h
deleted file mode 100644 (file)
index ca2dee0..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-
-#ifndef __IT8712_H__
-#define __IT8712_H__
-
-#define LPC_BASE_ADDR  0x14000000
-
-// MB PnP configuration register
-#define LPC_KEY_ADDR   0x1400002E
-#define LPC_DATA_ADDR  0x1400002F
-
-// Device LDN
-#define LDN_SERIAL1    0x01
-#define LDN_SERIAL2    0x02
-#define LDN_PARALLEL   0x03
-#define LDN_KEYBOARD   0x05
-#define LDN_MOUSE      0x06
-
-#define IT8712_UART1_PORT      0x3F8
-#define IT8712_UART2_PORT      0x2F8
-
-#ifndef ASM_ONLY
-
-void LPCSetConfig(char LdnNumber, char Index, char data);
-char LPCGetConfig(char LdnNumber, char Index);
-
-#endif
-
-#endif
index 13b1443a7a650b654bf367c28fb7219d7a073ce2..7e272ce57ea3a44ff42aa78270919516e2c39fa8 100644 (file)
@@ -42,6 +42,7 @@ extern unsigned long gt64120_base;
 #define EV64120_UART0_REGS_BASE        (KSEG1ADDR(EV64120_COM1_BASE_ADDR))
 #define EV64120_UART1_REGS_BASE        (KSEG1ADDR(EV64120_COM2_BASE_ADDR))
 #define EV64120_BASE_BAUD ( 3686400 / 16 )
+#define EV64120_UART_IRQ       6
 
 /*
  * PCI interrupts will come in on either the INTA or INTD interrups lines,
index 59d26b52ba321af8775bfee6edcb9de3191f1252..a13b715fd9caf5d028af465941d3f6c1f08ff193 100644 (file)
@@ -22,6 +22,7 @@ extern unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES];
 #define SD_NODE_INIT (struct sched_domain) {           \
        .span                   = CPU_MASK_NONE,        \
        .parent                 = NULL,                 \
+       .child                  = NULL,                 \
        .groups                 = NULL,                 \
        .min_interval           = 8,                    \
        .max_interval           = 32,                   \
index 4fb0fc43ffd71af828d8362052612b32b7fcafc1..5f3a9075cd28eaf2d0ad432a22fcd805e6aa63dc 100644 (file)
@@ -44,9 +44,8 @@ struct pt_regs {
        unsigned long cp0_epc;
 #ifdef CONFIG_MIPS_MT_SMTC
        unsigned long cp0_tcstatus;
-       unsigned long smtc_pad;
 #endif /* CONFIG_MIPS_MT_SMTC */
-};
+} __attribute__ ((aligned (8)));
 
 /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
 #define PTRACE_GETREGS         12
index 035637c67e7c0ab2c29b62f5d16dc7ce85b42c62..d7a65135d837ec20056d81083929836dc0e2782e 100644 (file)
  * Galileo EV64120 evaluation board
  */
 #ifdef CONFIG_MIPS_EV64120
-#include <asm/galileo-boards/ev96100.h>
-#include <asm/galileo-boards/ev96100int.h>
-#define EV96100_SERIAL_PORT_DEFNS                                  \
-    { .baud_base = EV96100_BASE_BAUD, .irq = EV96100INT_UART_0, \
+#include <mach-gt64120.h>
+#define EV64120_SERIAL_PORT_DEFNS                                  \
+    { .baud_base = EV64120_BASE_BAUD, .irq = EV64120_UART_IRQ, \
       .flags = STD_COM_FLAGS,  \
-      .iomem_base = EV96100_UART0_REGS_BASE, .iomem_reg_shift = 2, \
+      .iomem_base = EV64120_UART0_REGS_BASE, .iomem_reg_shift = 2, \
       .io_type = SERIAL_IO_MEM }, \
-    { .baud_base = EV96100_BASE_BAUD, .irq = EV96100INT_UART_0, \
+    { .baud_base = EV64120_BASE_BAUD, .irq = EV64120_UART_IRQ, \
       .flags = STD_COM_FLAGS, \
-      .iomem_base = EV96100_UART1_REGS_BASE, .iomem_reg_shift = 2, \
+      .iomem_base = EV64120_UART1_REGS_BASE, .iomem_reg_shift = 2, \
       .io_type = SERIAL_IO_MEM },
 #else
-#define EV96100_SERIAL_PORT_DEFNS
-#endif
-
-#ifdef CONFIG_MIPS_ITE8172
-#include <asm/it8172/it8172.h>
-#include <asm/it8172/it8172_int.h>
-#include <asm/it8712.h>
-#define ITE_SERIAL_PORT_DEFNS                                  \
-    { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_UART_BASE), \
-      .irq = IT8172_UART_IRQ, .flags = STD_COM_FLAGS, .port = PORT_16550 }, \
-    { .baud_base = (24000000/(16*13)), .port = (IT8172_PCI_IO_BASE + IT8712_UART1_PORT), \
-      .irq = IT8172_SERIRQ_4, .flags = STD_COM_FLAGS, .port = PORT_16550 }, \
-    /* Smart Card Reader 0 */ \
-    { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_SCR0_BASE), \
-      .irq = IT8172_SCR0_IRQ, .flags = STD_COM_FLAGS, .port = PORT_16550 }, \
-    /* Smart Card Reader 1 */ \
-    { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_SCR1_BASE), \
-      .irq = IT8172_SCR1_IRQ, .flags = STD_COM_FLAGS, .port = PORT_16550 },
-#else
-#define ITE_SERIAL_PORT_DEFNS
-#endif
-
-#ifdef CONFIG_MIPS_IVR
-#include <asm/it8172/it8172.h>
-#include <asm/it8172/it8172_int.h>
-#define IVR_SERIAL_PORT_DEFNS                                  \
-    { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_UART_BASE), \
-      .irq = IT8172_UART_IRQ, .flags = STD_COM_FLAGS, .port = PORT_16550 },         \
-    /* Smart Card Reader 1 */ \
-    { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_SCR1_BASE), \
-      .irq = IT8172_SCR1_IRQ, .flags = STD_COM_FLAGS, .port = PORT_16550 },
-#else
-#define IVR_SERIAL_PORT_DEFNS
+#define EV64120_SERIAL_PORT_DEFNS
 #endif
 
 #ifdef CONFIG_HAVE_STD_PC_SERIAL_PORT
 
 #define SERIAL_PORT_DFNS                               \
        DDB5477_SERIAL_PORT_DEFNS                       \
-       EV96100_SERIAL_PORT_DEFNS                       \
+       EV64120_SERIAL_PORT_DEFNS                       \
        IP32_SERIAL_PORT_DEFNS                          \
-       ITE_SERIAL_PORT_DEFNS                           \
-       IVR_SERIAL_PORT_DEFNS                           \
        JAZZ_SERIAL_PORT_DEFNS                          \
        STD_SERIAL_PORT_DEFNS                           \
        MOMENCO_OCELOT_G_SERIAL_PORT_DEFNS              \
diff --git a/include/asm-mips/stacktrace.h b/include/asm-mips/stacktrace.h
new file mode 100644 (file)
index 0000000..07f8733
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef _ASM_STACKTRACE_H
+#define _ASM_STACKTRACE_H
+
+#include <asm/ptrace.h>
+
+#ifdef CONFIG_KALLSYMS
+extern int raw_show_trace;
+extern unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
+                                 unsigned long pc, unsigned long *ra);
+#else
+#define raw_show_trace 1
+#define unwind_stack(task, sp, pc, ra) 0
+#endif
+
+static __always_inline void prepare_frametrace(struct pt_regs *regs)
+{
+#ifndef CONFIG_KALLSYMS
+       /*
+        * Remove any garbage that may be in regs (specially func
+        * addresses) to avoid show_raw_backtrace() to report them
+        */
+       memset(regs, 0, sizeof(*regs));
+#endif
+       __asm__ __volatile__(
+               ".set push\n\t"
+               ".set noat\n\t"
+#ifdef CONFIG_64BIT
+               "1: dla $1, 1b\n\t"
+               "sd $1, %0\n\t"
+               "sd $29, %1\n\t"
+               "sd $31, %2\n\t"
+#else
+               "1: la $1, 1b\n\t"
+               "sw $1, %0\n\t"
+               "sw $29, %1\n\t"
+               "sw $31, %2\n\t"
+#endif
+               ".set pop\n\t"
+               : "=m" (regs->cp0_epc),
+               "=m" (regs->regs[29]), "=m" (regs->regs[31])
+               : : "memory");
+}
+
+#endif /* _ASM_STACKTRACE_H */
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 c39142920fe6e61bd2610345fd8849a051c54676..685c91467e6347527567f5aa78198226ea236514 100644 (file)
@@ -1212,45 +1212,6 @@ type name (atype a,btype b,ctype c,dtype d,etype e,ftype f) \
 #  define __ARCH_WANT_COMPAT_SYS_TIME
 # endif
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/linkage.h>
-#include <asm/ptrace.h>
-#include <asm/sim.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-
-asmlinkage unsigned long sys_mmap(
-                               unsigned long addr, size_t len,
-                               int prot, int flags,
-                               int fd, off_t offset);
-asmlinkage long sys_mmap2(
-                       unsigned long addr, unsigned long len,
-                       unsigned long prot, unsigned long flags,
-                       unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs);
-asmlinkage int sys_pipe(nabi_no_regargs struct pt_regs regs);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-                               const struct sigaction __user *act,
-                               struct sigaction __user *oact,
-                               size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
 #endif /* !__ASSEMBLY__ */
 
 /*
diff --git a/include/asm-parisc/agp.h b/include/asm-parisc/agp.h
new file mode 100644 (file)
index 0000000..9f61d4e
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef _ASM_PARISC_AGP_H
+#define _ASM_PARISC_AGP_H
+
+/*
+ * PARISC specific AGP definitions.
+ * Copyright (c) 2006 Kyle McMartin <kyle@parisc-linux.org>
+ *
+ */
+
+#define map_page_into_agp(page)                /* nothing */
+#define unmap_page_from_agp(page)      /* nothing */
+#define flush_agp_mappings()           /* nothing */
+#define flush_agp_cache()              mb()
+
+/* Convert a physical address to an address suitable for the GART. */
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+
+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#define alloc_gatt_pages(order)                \
+       ((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order)  \
+       free_pages((unsigned long)(table), (order))
+
+#endif /* _ASM_PARISC_AGP_H */
index 1a7bfe699e0ccc5a33b5ab1a3c65e9b0822b780f..5a1e0e8b1c32d7843b77eccddc4049a46b27777c 100644 (file)
@@ -29,7 +29,8 @@
 #define LDREGX  ldd,s
 #define LDREGM ldd,mb
 #define STREGM std,ma
-#define SHRREG  shrd
+#define SHRREG shrd
+#define SHLREG shld
 #define RP_OFFSET      16
 #define FRAME_SIZE     128
 #define CALLEE_REG_FRAME_SIZE  144
@@ -39,7 +40,8 @@
 #define LDREGX  ldwx,s
 #define LDREGM ldwm
 #define STREGM stwm
-#define SHRREG  shr
+#define SHRREG shr
+#define SHLREG shlw
 #define RP_OFFSET      20
 #define FRAME_SIZE     64
 #define CALLEE_REG_FRAME_SIZE  128
index 0b459cdfbd6ffbe79d1b70781069d83949f1803e..2bc41f2e0271c21813c6c62273af0875a36db0df 100644 (file)
@@ -191,16 +191,38 @@ flush_anon_page(struct page *page, unsigned long vmaddr)
 }
 #define ARCH_HAS_FLUSH_ANON_PAGE
 
-static inline void
-flush_kernel_dcache_page(struct page *page)
+#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
+void flush_kernel_dcache_page_addr(void *addr);
+static inline void flush_kernel_dcache_page(struct page *page)
 {
-       flush_kernel_dcache_page_asm(page_address(page));
+       flush_kernel_dcache_page_addr(page_address(page));
 }
-#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
 
 #ifdef CONFIG_DEBUG_RODATA
 void mark_rodata_ro(void);
 #endif
 
+#ifdef CONFIG_PA8X00
+/* Only pa8800, pa8900 needs this */
+#define ARCH_HAS_KMAP
+
+void kunmap_parisc(void *addr);
+
+static inline void *kmap(struct page *page)
+{
+       might_sleep();
+       return page_address(page);
+}
+
+#define kunmap(page)                   kunmap_parisc(page_address(page))
+
+#define kmap_atomic(page, idx)         page_address(page)
+
+#define kunmap_atomic(addr, idx)       kunmap_parisc(addr)
+
+#define kmap_atomic_pfn(pfn, idx)      page_address(pfn_to_page(pfn))
+#define kmap_atomic_to_page(ptr)       virt_to_page(ptr)
+#endif
+
 #endif /* _PARISC_CACHEFLUSH_H */
 
index 71b4eeea205a1a85eda581179fd97b46eeee0e83..fe8579023531d5a8e8788eea06c7f672f161fa36 100644 (file)
@@ -5,7 +5,7 @@
  */
 #include <linux/types.h>
 #include <linux/sched.h>
-#include <linux/personality.h>
+#include <linux/thread_info.h>
 
 #define COMPAT_USER_HZ 100
 
@@ -152,7 +152,7 @@ static __inline__ void __user *compat_alloc_user_space(long len)
 
 static inline int __is_compat_task(struct task_struct *t)
 {
-       return personality(t->personality) == PER_LINUX32;
+       return test_ti_thread_flag(t->thread_info, TIF_32BIT);
 }
 
 static inline int is_compat_task(void)
index 9979c3cb37454a23e53a3d7ce2d300a8bd11a3f7..da2cf373e31c54af3e746e95d87d08656299b518 100644 (file)
 #define DMA2_MASK_ALL_REG       0xDE    /* all-channels mask (w) */
 #define DMA2_EXT_MODE_REG      (0x400 | DMA2_MODE_REG)
 
-extern spinlock_t dma_spin_lock;
-
 static __inline__ unsigned long claim_dma_lock(void)
 {
-       unsigned long flags;
-       spin_lock_irqsave(&dma_spin_lock, flags);
-       return flags;
+       return 0;
 }
 
 static __inline__ void release_dma_lock(unsigned long flags)
 {
-       spin_unlock_irqrestore(&dma_spin_lock, flags);
 }
 
 
index 6a332a9f099c2eafbf78ee5f79056a349d41a775..d84bbb283fd17c7a8e9fb92d4a30a660efe86263 100644 (file)
@@ -1,6 +1,71 @@
-#ifndef _ASM_FUTEX_H
-#define _ASM_FUTEX_H
+#ifndef _ASM_PARISC_FUTEX_H
+#define _ASM_PARISC_FUTEX_H
 
-#include <asm-generic/futex.h>
+#ifdef __KERNEL__
 
+#include <linux/futex.h>
+#include <asm/errno.h>
+#include <asm/uaccess.h>
+
+static inline int
+futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
+{
+       int op = (encoded_op >> 28) & 7;
+       int cmp = (encoded_op >> 24) & 15;
+       int oparg = (encoded_op << 8) >> 20;
+       int cmparg = (encoded_op << 20) >> 20;
+       int oldval = 0, ret;
+       if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
+               oparg = 1 << oparg;
+
+       if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
+               return -EFAULT;
+
+       inc_preempt_count();
+
+       switch (op) {
+       case FUTEX_OP_SET:
+       case FUTEX_OP_ADD:
+       case FUTEX_OP_OR:
+       case FUTEX_OP_ANDN:
+       case FUTEX_OP_XOR:
+       default:
+               ret = -ENOSYS;
+       }
+
+       dec_preempt_count();
+
+       if (!ret) {
+               switch (cmp) {
+               case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
+               case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
+               case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
+               case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
+               case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
+               case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
+               default: ret = -ENOSYS;
+               }
+       }
+       return ret;
+}
+
+/* Non-atomic version */
+static inline int
+futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
+{
+       int err = 0;
+       int uval;
+
+       if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
+               return -EFAULT;
+
+       err = get_user(uval, uaddr);
+       if (err) return -EFAULT;
+       if (uval == oldval)
+               err = put_user(newval, uaddr);
+       if (err) return -EFAULT;
+       return uval;
+}
+
+#endif
 #endif
index b9eb245b88749f16ea144fac741942041f30dc27..c1963ce19dd26df0fa7fd3977a0f6592e769dae6 100644 (file)
@@ -134,7 +134,7 @@ extern inline void __iomem * ioremap(unsigned long offset, unsigned long size)
 }
 #define ioremap_nocache(off, sz)       ioremap((off), (sz))
 
-extern void iounmap(void __iomem *addr);
+extern void iounmap(const volatile void __iomem *addr);
 
 static inline unsigned char __raw_readb(const volatile void __iomem *addr)
 {
diff --git a/include/asm-parisc/iosapic.h b/include/asm-parisc/iosapic.h
deleted file mode 100644 (file)
index 613390e..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
-** This file is private to iosapic driver.
-** If stuff needs to be used by another driver, move it to a common file.
-**
-** WARNING: fields most data structures here are ordered to make sure
-**          they pack nicely for 64-bit compilation. (ie sizeof(long) == 8)
-*/
-
-
-/*
-** I/O SAPIC init function
-** Caller knows where an I/O SAPIC is. LBA has an integrated I/O SAPIC.
-** Call setup as part of per instance initialization.
-** (ie *not* init_module() function unless only one is present.)
-** fixup_irq is to initialize PCI IRQ line support and
-** virtualize pcidev->irq value. To be called by pci_fixup_bus().
-*/
-extern void *iosapic_register(unsigned long hpa);
-extern int iosapic_fixup_irq(void *obj, struct pci_dev *pcidev);
-
-
-#ifdef __IA64__
-/*
-** PA: PIB (Processor Interrupt Block) is handled by Runway bus adapter.
-**     and is hardcoded to 0xfeeNNNN0 where NNNN is id_eid field.
-**
-** IA64: PIB is handled by "Local SAPIC" (integrated in the processor).
-*/
-struct local_sapic_info {
-       struct local_sapic_info *lsi_next;      /* point to next CPU info */
-       int                     *lsi_cpu_id;    /* point to logical CPU id */
-       unsigned long           *lsi_id_eid;    /* point to IA-64 CPU id */
-       int                     *lsi_status;    /* point to CPU status   */
-       void                    *lsi_private;   /* point to special info */
-};
-
-/*
-** "root" data structure which ties everything together.
-** Should always be able to start with sapic_root and locate
-** the desired information.
-*/
-struct sapic_info {
-       struct sapic_info       *si_next;       /* info is per cell */
-       int                     si_cellid;      /* cell id */
-       unsigned int            si_status;       /* status  */
-       char                    *si_pib_base;   /* intr blk base address */
-       local_sapic_info_t      *si_local_info;
-       io_sapic_info_t         *si_io_info;
-       extint_info_t           *si_extint_info;/* External Intr info      */
-};
-
-#endif /* IA64 */
-
index 5cae260615a22a74d14075d529a47419e9d02137..399c81981ed5a2081e8a4a32dff54c341d2036af 100644 (file)
@@ -31,7 +31,7 @@ static __inline__ int irq_canonicalize(int irq)
        return (irq == 2) ? 9 : irq;
 }
 
-struct hw_interrupt_type;
+struct irq_chip;
 
 /*
  * Some useful "we don't have to do anything here" handlers.  Should
@@ -39,6 +39,8 @@ struct hw_interrupt_type;
  */
 void no_ack_irq(unsigned int irq);
 void no_end_irq(unsigned int irq);
+void cpu_ack_irq(unsigned int irq);
+void cpu_end_irq(unsigned int irq);
 
 extern int txn_alloc_irq(unsigned int nbits);
 extern int txn_claim_irq(int);
@@ -46,7 +48,7 @@ extern unsigned int txn_alloc_data(unsigned int);
 extern unsigned long txn_alloc_addr(unsigned int);
 extern unsigned long txn_affinity_addr(unsigned int irq, int cpu);
 
-extern int cpu_claim_irq(unsigned int irq, struct hw_interrupt_type *, void *);
+extern int cpu_claim_irq(unsigned int irq, struct irq_chip *, void *);
 extern int cpu_check_affinity(unsigned int irq, cpumask_t *dest);
 
 /* soft power switch support (power.c) */
diff --git a/include/asm-parisc/mckinley.h b/include/asm-parisc/mckinley.h
new file mode 100644 (file)
index 0000000..d1ea6f1
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef ASM_PARISC_MCKINLEY_H
+#define ASM_PARISC_MCKINLEY_H
+#ifdef __KERNEL__
+
+/* declared in arch/parisc/kernel/setup.c */
+extern struct proc_dir_entry * proc_mckinley_root;
+
+#endif /*__KERNEL__*/
+#endif /*ASM_PARISC_MCKINLEY_H*/
index 57d6d82756dd678d54a7f261859730f8c998e3bb..3567208191e37d09f47199a26a0a223dce1b6c28 100644 (file)
 
 struct page;
 
-extern void purge_kernel_dcache_page(unsigned long);
-extern void copy_user_page_asm(void *to, void *from);
-extern void clear_user_page_asm(void *page, unsigned long vaddr);
-
-static inline void
-copy_user_page(void *vto, void *vfrom, unsigned long vaddr, struct page *pg)
-{
-       copy_user_page_asm(vto, vfrom);
-       flush_kernel_dcache_page_asm(vto);
-       /* XXX: ppc flushes icache too, should we? */
-}
-
-static inline void
-clear_user_page(void *page, unsigned long vaddr, struct page *pg)
-{
-       purge_kernel_dcache_page((unsigned long)page);
-       clear_user_page_asm(page, vaddr);
-}
+void copy_user_page_asm(void *to, void *from);
+void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
+                          struct page *pg);
+void clear_user_page(void *page, unsigned long vaddr, struct page *pg);
 
 /*
  * These are used to make use of C type-checking..
index 07cb9b93cfe25e30bf449f47ac2275fdf6ac9781..32e03d8778587806cb001c9f6b98df3f1763e256 100644 (file)
@@ -2,13 +2,9 @@
 #define _ASMPARISC_PARAM_H
 
 #ifdef __KERNEL__
-# ifdef CONFIG_PA20
-#  define HZ           1000            /* Faster machines */
-# else
-#  define HZ           100             /* Internal kernel timer frequency */
-# endif
-# define USER_HZ       100             /* .. some user interfaces are in "ticks" */
-# define CLOCKS_PER_SEC        (USER_HZ)       /* like times() */
+#define HZ             CONFIG_HZ
+#define USER_HZ                100             /* some user API use "ticks" */
+#define CLOCKS_PER_SEC (USER_HZ)       /* like times() */
 #endif
 
 #ifndef HZ
index 1d247e32a6088e180284e5fb7be23ed8ce83f464..e12624d8941d69cbc6bb35bb70d452d70642b428 100644 (file)
@@ -1,3 +1,6 @@
+#ifndef _ASM_PARISC_PARISC_DEVICE_H_
+#define _ASM_PARISC_PARISC_DEVICE_H_
+
 #include <linux/device.h>
 
 struct parisc_device {
@@ -57,3 +60,5 @@ parisc_get_drvdata(struct parisc_device *d)
 }
 
 extern struct bus_type parisc_bus_type;
+
+#endif /*_ASM_PARISC_PARISC_DEVICE_H_*/
index 8b631f47eb257b90a8a472bd8ed1cbf290d07631..7b8ad118d2feec1b9b307d442cbe666abdb2640e 100644 (file)
@@ -293,4 +293,9 @@ static inline void pcibios_penalize_isa_irq(int irq, int active)
        /* We don't need to penalize isa irq's */
 }
 
+static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
+{
+       return channel ? 15 : 14;
+}
+
 #endif /* __ASM_PARISC_PCI_H */
diff --git a/include/asm-parisc/prefetch.h b/include/asm-parisc/prefetch.h
new file mode 100644 (file)
index 0000000..5d02172
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * include/asm-parisc/prefetch.h
+ *
+ * PA 2.0 defines data prefetch instructions on page 6-11 of the Kane book.
+ * In addition, many implementations do hardware prefetching of both
+ * instructions and data.
+ *
+ * PA7300LC (page 14-4 of the ERS) also implements prefetching by a load
+ * to gr0 but not in a way that Linux can use.  If the load would cause an
+ * interruption (eg due to prefetching 0), it is suppressed on PA2.0
+ * processors, but not on 7300LC.
+ *
+ */
+
+#ifndef __ASM_PARISC_PREFETCH_H
+#define __ASM_PARISC_PREFETCH_H
+
+#ifndef __ASSEMBLY__
+#ifdef CONFIG_PREFETCH
+
+#define ARCH_HAS_PREFETCH
+extern inline void prefetch(const void *addr)
+{
+       __asm__("ldw 0(%0), %%r0" : : "r" (addr));
+}
+
+/* LDD is a PA2.0 addition. */
+#ifdef CONFIG_PA20
+#define ARCH_HAS_PREFETCHW
+extern inline void prefetchw(const void *addr)
+{
+       __asm__("ldd 0(%0), %%r0" : : "r" (addr));
+}
+#endif /* CONFIG_PA20 */
+
+#endif /* CONFIG_PREFETCH */
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_PARISC_PROCESSOR_H */
index b73626f040dace5eb8d091636be645ed564864a0..fd7866dc8c83462b2d8a3274ac4118b5315de8d2 100644 (file)
@@ -9,6 +9,8 @@
 #define __ASM_PARISC_PROCESSOR_H
 
 #ifndef __ASSEMBLY__
+#include <asm/prefetch.h>      /* lockdep.h needs <linux/prefetch.h> */
+
 #include <linux/threads.h>
 #include <linux/spinlock_types.h>
 
@@ -276,7 +278,7 @@ on downward growing arches, it looks like this:
  */
 
 #ifdef __LP64__
-#define USER_WIDE_MODE (personality(current->personality) == PER_LINUX)
+#define USER_WIDE_MODE (!test_thread_flag(TIF_32BIT))
 #else
 #define USER_WIDE_MODE 0
 #endif
@@ -328,33 +330,20 @@ extern unsigned long get_wchan(struct task_struct *p);
 #define KSTK_EIP(tsk)  ((tsk)->thread.regs.iaoq[0])
 #define KSTK_ESP(tsk)  ((tsk)->thread.regs.gr[30])
 
+#define cpu_relax()    barrier()
 
-/*
- * PA 2.0 defines data prefetch instructions on page 6-11 of the Kane book.
- * In addition, many implementations do hardware prefetching of both
- * instructions and data.
- *
- * PA7300LC (page 14-4 of the ERS) also implements prefetching by a load
- * to gr0 but not in a way that Linux can use.  If the load would cause an
- * interruption (eg due to prefetching 0), it is suppressed on PA2.0
- * processors, but not on 7300LC.
- */
-#ifdef  CONFIG_PREFETCH
-#define ARCH_HAS_PREFETCH
-#define ARCH_HAS_PREFETCHW
-
-extern inline void prefetch(const void *addr)
-{
-       __asm__("ldw 0(%0), %%r0" : : "r" (addr));
-}
-
-extern inline void prefetchw(const void *addr)
+/* Used as a macro to identify the combined VIPT/PIPT cached
+ * CPUs which require a guarantee of coherency (no inequivalent
+ * aliases with different data, whether clean or not) to operate */
+static inline int parisc_requires_coherency(void)
 {
-       __asm__("ldd 0(%0), %%r0" : : "r" (addr));
-}
+#ifdef CONFIG_PA8X00
+       /* FIXME: also pa8900 - when we see one */
+       return boot_cpu_data.cpu_type == mako;
+#else
+       return 0;
 #endif
-
-#define cpu_relax()    barrier()
+}
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/include/asm-parisc/ropes.h b/include/asm-parisc/ropes.h
new file mode 100644 (file)
index 0000000..5542dd0
--- /dev/null
@@ -0,0 +1,322 @@
+#ifndef _ASM_PARISC_ROPES_H_
+#define _ASM_PARISC_ROPES_H_
+
+#include <asm-parisc/parisc-device.h>
+
+#ifdef CONFIG_64BIT
+/* "low end" PA8800 machines use ZX1 chipset: PAT PDC and only run 64-bit */
+#define ZX1_SUPPORT
+#endif
+
+#ifdef CONFIG_PROC_FS
+/* depends on proc fs support. But costs CPU performance */
+#undef SBA_COLLECT_STATS
+#endif
+
+/*
+** The number of pdir entries to "free" before issueing
+** a read to PCOM register to flush out PCOM writes.
+** Interacts with allocation granularity (ie 4 or 8 entries
+** allocated and free'd/purged at a time might make this
+** less interesting).
+*/
+#define DELAYED_RESOURCE_CNT   16
+
+#define MAX_IOC                2       /* per Ike. Pluto/Astro only have 1. */
+#define ROPES_PER_IOC  8       /* per Ike half or Pluto/Astro */
+
+struct ioc {
+       void __iomem    *ioc_hpa;       /* I/O MMU base address */
+       char            *res_map;       /* resource map, bit == pdir entry */
+       u64             *pdir_base;     /* physical base address */
+       unsigned long   ibase;          /* pdir IOV Space base - shared w/lba_pci */
+       unsigned long   imask;          /* pdir IOV Space mask - shared w/lba_pci */
+#ifdef ZX1_SUPPORT
+       unsigned long   iovp_mask;      /* help convert IOVA to IOVP */
+#endif
+       unsigned long   *res_hint;      /* next avail IOVP - circular search */
+       spinlock_t      res_lock;
+       unsigned int    res_bitshift;   /* from the LEFT! */
+       unsigned int    res_size;       /* size of resource map in bytes */
+#ifdef SBA_HINT_SUPPORT
+/* FIXME : DMA HINTs not used */
+       unsigned long   hint_mask_pdir; /* bits used for DMA hints */
+       unsigned int    hint_shift_pdir;
+#endif
+#if DELAYED_RESOURCE_CNT > 0
+       int             saved_cnt;
+       struct sba_dma_pair {
+                       dma_addr_t      iova;
+                       size_t          size;
+        } saved[DELAYED_RESOURCE_CNT];
+#endif
+
+#ifdef SBA_COLLECT_STATS
+#define SBA_SEARCH_SAMPLE      0x100
+       unsigned long   avg_search[SBA_SEARCH_SAMPLE];
+       unsigned long   avg_idx;        /* current index into avg_search */
+       unsigned long   used_pages;
+       unsigned long   msingle_calls;
+       unsigned long   msingle_pages;
+       unsigned long   msg_calls;
+       unsigned long   msg_pages;
+       unsigned long   usingle_calls;
+       unsigned long   usingle_pages;
+       unsigned long   usg_calls;
+       unsigned long   usg_pages;
+#endif
+        /* STUFF We don't need in performance path */
+       unsigned int    pdir_size;      /* in bytes, determined by IOV Space size */
+};
+
+struct sba_device {
+       struct sba_device       *next;  /* list of SBA's in system */
+       struct parisc_device    *dev;   /* dev found in bus walk */
+       const char              *name;
+       void __iomem            *sba_hpa; /* base address */
+       spinlock_t              sba_lock;
+       unsigned int            flags;  /* state/functionality enabled */
+       unsigned int            hw_rev;  /* HW revision of chip */
+
+       struct resource         chip_resv; /* MMIO reserved for chip */
+       struct resource         iommu_resv; /* MMIO reserved for iommu */
+
+       unsigned int            num_ioc;  /* number of on-board IOC's */
+       struct ioc              ioc[MAX_IOC];
+};
+
+#define ASTRO_RUNWAY_PORT      0x582
+#define IKE_MERCED_PORT                0x803
+#define REO_MERCED_PORT                0x804
+#define REOG_MERCED_PORT       0x805
+#define PLUTO_MCKINLEY_PORT    0x880
+
+static inline int IS_ASTRO(struct parisc_device *d) {
+       return d->id.hversion == ASTRO_RUNWAY_PORT;
+}
+
+static inline int IS_IKE(struct parisc_device *d) {
+       return d->id.hversion == IKE_MERCED_PORT;
+}
+
+static inline int IS_PLUTO(struct parisc_device *d) {
+       return d->id.hversion == PLUTO_MCKINLEY_PORT;
+}
+
+#define PLUTO_IOVA_BASE        (1UL*1024*1024*1024)    /* 1GB */
+#define PLUTO_IOVA_SIZE        (1UL*1024*1024*1024)    /* 1GB */
+#define PLUTO_GART_SIZE        (PLUTO_IOVA_SIZE / 2)
+
+#define SBA_PDIR_VALID_BIT     0x8000000000000000ULL
+
+#define SBA_AGPGART_COOKIE     0x0000badbadc0ffeeULL
+
+#define SBA_FUNC_ID    0x0000  /* function id */
+#define SBA_FCLASS     0x0008  /* function class, bist, header, rev... */
+
+#define SBA_FUNC_SIZE 4096   /* SBA configuration function reg set */
+
+#define ASTRO_IOC_OFFSET       (32 * SBA_FUNC_SIZE)
+#define PLUTO_IOC_OFFSET       (1 * SBA_FUNC_SIZE)
+/* Ike's IOC's occupy functions 2 and 3 */
+#define IKE_IOC_OFFSET(p)      ((p+2) * SBA_FUNC_SIZE)
+
+#define IOC_CTRL          0x8  /* IOC_CTRL offset */
+#define IOC_CTRL_TC       (1 << 0) /* TOC Enable */
+#define IOC_CTRL_CE       (1 << 1) /* Coalesce Enable */
+#define IOC_CTRL_DE       (1 << 2) /* Dillon Enable */
+#define IOC_CTRL_RM       (1 << 8) /* Real Mode */
+#define IOC_CTRL_NC       (1 << 9) /* Non Coherent Mode */
+#define IOC_CTRL_D4       (1 << 11) /* Disable 4-byte coalescing */
+#define IOC_CTRL_DD       (1 << 13) /* Disable distr. LMMIO range coalescing */
+
+/*
+** Offsets into MBIB (Function 0 on Ike and hopefully Astro)
+** Firmware programs this stuff. Don't touch it.
+*/
+#define LMMIO_DIRECT0_BASE  0x300
+#define LMMIO_DIRECT0_MASK  0x308
+#define LMMIO_DIRECT0_ROUTE 0x310
+
+#define LMMIO_DIST_BASE  0x360
+#define LMMIO_DIST_MASK  0x368
+#define LMMIO_DIST_ROUTE 0x370
+
+#define IOS_DIST_BASE  0x390
+#define IOS_DIST_MASK  0x398
+#define IOS_DIST_ROUTE 0x3A0
+
+#define IOS_DIRECT_BASE        0x3C0
+#define IOS_DIRECT_MASK        0x3C8
+#define IOS_DIRECT_ROUTE 0x3D0
+
+/*
+** Offsets into I/O TLB (Function 2 and 3 on Ike)
+*/
+#define ROPE0_CTL      0x200  /* "regbus pci0" */
+#define ROPE1_CTL      0x208
+#define ROPE2_CTL      0x210
+#define ROPE3_CTL      0x218
+#define ROPE4_CTL      0x220
+#define ROPE5_CTL      0x228
+#define ROPE6_CTL      0x230
+#define ROPE7_CTL      0x238
+
+#define IOC_ROPE0_CFG  0x500   /* pluto only */
+#define   IOC_ROPE_AO    0x10  /* Allow "Relaxed Ordering" */
+
+#define HF_ENABLE      0x40
+
+#define IOC_IBASE      0x300   /* IO TLB */
+#define IOC_IMASK      0x308
+#define IOC_PCOM       0x310
+#define IOC_TCNFG      0x318
+#define IOC_PDIR_BASE  0x320
+
+/*
+** IOC supports 4/8/16/64KB page sizes (see TCNFG register)
+** It's safer (avoid memory corruption) to keep DMA page mappings
+** equivalently sized to VM PAGE_SIZE.
+**
+** We really can't avoid generating a new mapping for each
+** page since the Virtual Coherence Index has to be generated
+** and updated for each page.
+**
+** PAGE_SIZE could be greater than IOVP_SIZE. But not the inverse.
+*/
+#define IOVP_SIZE      PAGE_SIZE
+#define IOVP_SHIFT     PAGE_SHIFT
+#define IOVP_MASK      PAGE_MASK
+
+#define SBA_PERF_CFG   0x708   /* Performance Counter stuff */
+#define SBA_PERF_MASK1 0x718
+#define SBA_PERF_MASK2 0x730
+
+/*
+** Offsets into PCI Performance Counters (functions 12 and 13)
+** Controlled by PERF registers in function 2 & 3 respectively.
+*/
+#define SBA_PERF_CNT1  0x200
+#define SBA_PERF_CNT2  0x208
+#define SBA_PERF_CNT3  0x210
+
+/*
+** lba_device: Per instance Elroy data structure
+*/
+struct lba_device {
+       struct pci_hba_data     hba;
+
+       spinlock_t              lba_lock;
+       void                    *iosapic_obj;
+
+#ifdef CONFIG_64BIT
+       void __iomem            *iop_base;      /* PA_VIEW - for IO port accessor funcs */
+#endif
+
+       int                     flags;          /* state/functionality enabled */
+       int                     hw_rev;         /* HW revision of chip */
+};
+
+#define ELROY_HVERS            0x782
+#define MERCURY_HVERS          0x783
+#define QUICKSILVER_HVERS      0x784
+
+static inline int IS_ELROY(struct parisc_device *d) {
+       return (d->id.hversion == ELROY_HVERS);
+}
+
+static inline int IS_MERCURY(struct parisc_device *d) {
+       return (d->id.hversion == MERCURY_HVERS);
+}
+
+static inline int IS_QUICKSILVER(struct parisc_device *d) {
+       return (d->id.hversion == QUICKSILVER_HVERS);
+}
+
+static inline int agp_mode_mercury(void __iomem *hpa) {
+       u64 bus_mode;
+
+       bus_mode = readl(hpa + 0x0620);
+       if (bus_mode & 1)
+               return 1;
+
+       return 0;
+}
+
+/*
+** I/O SAPIC init function
+** Caller knows where an I/O SAPIC is. LBA has an integrated I/O SAPIC.
+** Call setup as part of per instance initialization.
+** (ie *not* init_module() function unless only one is present.)
+** fixup_irq is to initialize PCI IRQ line support and
+** virtualize pcidev->irq value. To be called by pci_fixup_bus().
+*/
+extern void *iosapic_register(unsigned long hpa);
+extern int iosapic_fixup_irq(void *obj, struct pci_dev *pcidev);
+
+#define LBA_FUNC_ID    0x0000  /* function id */
+#define LBA_FCLASS     0x0008  /* function class, bist, header, rev... */
+#define LBA_CAPABLE    0x0030  /* capabilities register */
+
+#define LBA_PCI_CFG_ADDR       0x0040  /* poke CFG address here */
+#define LBA_PCI_CFG_DATA       0x0048  /* read or write data here */
+
+#define LBA_PMC_MTLT   0x0050  /* Firmware sets this - read only. */
+#define LBA_FW_SCRATCH 0x0058  /* Firmware writes the PCI bus number here. */
+#define LBA_ERROR_ADDR 0x0070  /* On error, address gets logged here */
+
+#define LBA_ARB_MASK   0x0080  /* bit 0 enable arbitration. PAT/PDC enables */
+#define LBA_ARB_PRI    0x0088  /* firmware sets this. */
+#define LBA_ARB_MODE   0x0090  /* firmware sets this. */
+#define LBA_ARB_MTLT   0x0098  /* firmware sets this. */
+
+#define LBA_MOD_ID     0x0100  /* Module ID. PDC_PAT_CELL reports 4 */
+
+#define LBA_STAT_CTL   0x0108  /* Status & Control */
+#define   LBA_BUS_RESET                0x01    /*  Deassert PCI Bus Reset Signal */
+#define   CLEAR_ERRLOG         0x10    /*  "Clear Error Log" cmd */
+#define   CLEAR_ERRLOG_ENABLE  0x20    /*  "Clear Error Log" Enable */
+#define   HF_ENABLE    0x40    /*    enable HF mode (default is -1 mode) */
+
+#define LBA_LMMIO_BASE 0x0200  /* < 4GB I/O address range */
+#define LBA_LMMIO_MASK 0x0208
+
+#define LBA_GMMIO_BASE 0x0210  /* > 4GB I/O address range */
+#define LBA_GMMIO_MASK 0x0218
+
+#define LBA_WLMMIO_BASE        0x0220  /* All < 4GB ranges under the same *SBA* */
+#define LBA_WLMMIO_MASK        0x0228
+
+#define LBA_WGMMIO_BASE        0x0230  /* All > 4GB ranges under the same *SBA* */
+#define LBA_WGMMIO_MASK        0x0238
+
+#define LBA_IOS_BASE   0x0240  /* I/O port space for this LBA */
+#define LBA_IOS_MASK   0x0248
+
+#define LBA_ELMMIO_BASE        0x0250  /* Extra LMMIO range */
+#define LBA_ELMMIO_MASK        0x0258
+
+#define LBA_EIOS_BASE  0x0260  /* Extra I/O port space */
+#define LBA_EIOS_MASK  0x0268
+
+#define LBA_GLOBAL_MASK        0x0270  /* Mercury only: Global Address Mask */
+#define LBA_DMA_CTL    0x0278  /* firmware sets this */
+
+#define LBA_IBASE      0x0300  /* SBA DMA support */
+#define LBA_IMASK      0x0308
+
+/* FIXME: ignore DMA Hint stuff until we can measure performance */
+#define LBA_HINT_CFG   0x0310
+#define LBA_HINT_BASE  0x0380  /* 14 registers at every 8 bytes. */
+
+#define LBA_BUS_MODE   0x0620
+
+/* ERROR regs are needed for config cycle kluges */
+#define LBA_ERROR_CONFIG 0x0680
+#define     LBA_SMART_MODE 0x20
+#define LBA_ERROR_STATUS 0x0688
+#define LBA_ROPE_CTL     0x06A0
+
+#define LBA_IOSAPIC_BASE       0x800 /* Offset of IRQ logic */
+
+#endif /*_ASM_PARISC_ROPES_H_*/
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 82fd820d684f090137e5a6c53d7c1adfb7fea263..d7e3cc60dbc3693a3b8ce475fbd128bb9563a284 100644 (file)
@@ -3,20 +3,8 @@
  */
 
 /*
- * This assumes you have a 7.272727 MHz clock for your UART.
- * The documentation implies a 40Mhz clock, and elsewhere a 7Mhz clock
- * Clarified: 7.2727MHz on LASI. Not yet clarified for DINO
+ * This is used for 16550-compatible UARTs
  */
+#define BASE_BAUD ( 1843200 / 16 )
 
-#define LASI_BASE_BAUD ( 7272727 / 16 )
-#define BASE_BAUD  LASI_BASE_BAUD
-
-/*
- * We don't use the ISA probing code, so these entries are just to reserve
- * space.  Some example (maximal) configurations:
- * - 712 w/ additional Lasi & RJ16 ports: 4
- * - J5k w/ PCI serial cards: 2 + 4 * card ~= 34
- * A500 w/ PCI serial cards: 5 + 4 * card ~= 17
- */
 #define SERIAL_PORT_DFNS
index e1825530365d3d1724b925fabb54a125429cd564..f3d2090a18dc316e5a4cbd388abb32e94717b764 100644 (file)
@@ -56,50 +56,79 @@ static inline int __raw_spin_trylock(raw_spinlock_t *x)
 }
 
 /*
- * Read-write spinlocks, allowing multiple readers
- * but only one writer.
+ * Read-write spinlocks, allowing multiple readers but only one writer.
+ * Linux rwlocks are unfair to writers; they can be starved for an indefinite
+ * time by readers.  With care, they can also be taken in interrupt context.
+ *
+ * In the PA-RISC implementation, we have a spinlock and a counter.
+ * Readers use the lock to serialise their access to the counter (which
+ * records how many readers currently hold the lock).
+ * Writers hold the spinlock, preventing any readers or other writers from
+ * grabbing the rwlock.
  */
 
-#define __raw_read_trylock(lock) generic__raw_read_trylock(lock)
-
-/* read_lock, read_unlock are pretty straightforward.  Of course it somehow
- * sucks we end up saving/restoring flags twice for read_lock_irqsave aso. */
-
+/* Note that we have to ensure interrupts are disabled in case we're
+ * interrupted by some other code that wants to grab the same read lock */
 static  __inline__ void __raw_read_lock(raw_rwlock_t *rw)
 {
-       __raw_spin_lock(&rw->lock);
-
+       unsigned long flags;
+       local_irq_save(flags);
+       __raw_spin_lock_flags(&rw->lock, flags);
        rw->counter++;
-
        __raw_spin_unlock(&rw->lock);
+       local_irq_restore(flags);
 }
 
+/* Note that we have to ensure interrupts are disabled in case we're
+ * interrupted by some other code that wants to grab the same read lock */
 static  __inline__ void __raw_read_unlock(raw_rwlock_t *rw)
 {
-       __raw_spin_lock(&rw->lock);
-
+       unsigned long flags;
+       local_irq_save(flags);
+       __raw_spin_lock_flags(&rw->lock, flags);
        rw->counter--;
-
        __raw_spin_unlock(&rw->lock);
+       local_irq_restore(flags);
 }
 
-/* write_lock is less trivial.  We optimistically grab the lock and check
- * if we surprised any readers.  If so we release the lock and wait till
- * they're all gone before trying again
- *
- * Also note that we don't use the _irqsave / _irqrestore suffixes here.
- * If we're called with interrupts enabled and we've got readers (or other
- * writers) in interrupt handlers someone fucked up and we'd dead-lock
- * sooner or later anyway.   prumpf */
+/* Note that we have to ensure interrupts are disabled in case we're
+ * interrupted by some other code that wants to grab the same read lock */
+static __inline__ int __raw_read_trylock(raw_rwlock_t *rw)
+{
+       unsigned long flags;
+ retry:
+       local_irq_save(flags);
+       if (__raw_spin_trylock(&rw->lock)) {
+               rw->counter++;
+               __raw_spin_unlock(&rw->lock);
+               local_irq_restore(flags);
+               return 1;
+       }
 
-static  __inline__ void __raw_write_lock(raw_rwlock_t *rw)
+       local_irq_restore(flags);
+       /* If write-locked, we fail to acquire the lock */
+       if (rw->counter < 0)
+               return 0;
+
+       /* Wait until we have a realistic chance at the lock */
+       while (__raw_spin_is_locked(&rw->lock) && rw->counter >= 0)
+               cpu_relax();
+
+       goto retry;
+}
+
+/* Note that we have to ensure interrupts are disabled in case we're
+ * interrupted by some other code that wants to read_trylock() this lock */
+static __inline__ void __raw_write_lock(raw_rwlock_t *rw)
 {
+       unsigned long flags;
 retry:
-       __raw_spin_lock(&rw->lock);
+       local_irq_save(flags);
+       __raw_spin_lock_flags(&rw->lock, flags);
 
-       if(rw->counter != 0) {
-               /* this basically never happens */
+       if (rw->counter != 0) {
                __raw_spin_unlock(&rw->lock);
+               local_irq_restore(flags);
 
                while (rw->counter != 0)
                        cpu_relax();
@@ -107,31 +136,37 @@ retry:
                goto retry;
        }
 
-       /* got it.  now leave without unlocking */
-       rw->counter = -1; /* remember we are locked */
+       rw->counter = -1; /* mark as write-locked */
+       mb();
+       local_irq_restore(flags);
 }
 
-/* write_unlock is absolutely trivial - we don't have to wait for anything */
-
-static  __inline__ void __raw_write_unlock(raw_rwlock_t *rw)
+static __inline__ void __raw_write_unlock(raw_rwlock_t *rw)
 {
        rw->counter = 0;
        __raw_spin_unlock(&rw->lock);
 }
 
-static  __inline__ int __raw_write_trylock(raw_rwlock_t *rw)
+/* Note that we have to ensure interrupts are disabled in case we're
+ * interrupted by some other code that wants to read_trylock() this lock */
+static __inline__ int __raw_write_trylock(raw_rwlock_t *rw)
 {
-       __raw_spin_lock(&rw->lock);
-       if (rw->counter != 0) {
-               /* this basically never happens */
-               __raw_spin_unlock(&rw->lock);
-
-               return 0;
+       unsigned long flags;
+       int result = 0;
+
+       local_irq_save(flags);
+       if (__raw_spin_trylock(&rw->lock)) {
+               if (rw->counter == 0) {
+                       rw->counter = -1;
+                       result = 1;
+               } else {
+                       /* Read-locked.  Oh well. */
+                       __raw_spin_unlock(&rw->lock);
+               }
        }
+       local_irq_restore(flags);
 
-       /* got it.  now leave without unlocking */
-       rw->counter = -1; /* remember we are locked */
-       return 1;
+       return result;
 }
 
 /*
index 27bcfad1c3e337cf3642245c3430dba14202ccb4..53b0f5d290e457d405d2950cb8982693658514df 100644 (file)
@@ -952,92 +952,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)      \
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 
-/* mmap & mmap2 take 6 arguments */
-#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \
-{                                                                              \
-    return K_INLINE_SYSCALL(name, 6, arg1, arg2, arg3, arg4, arg5, arg6);      \
-}
-
-#ifdef __KERNEL_SYSCALLS__
-
-#include <asm/current.h>
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/syscalls.h>
-
-static inline pid_t setsid(void)
-{
-       return sys_setsid();
-}
-
-static inline int write(int fd, const char *buf, off_t count)
-{
-       return sys_write(fd, buf, count);
-}
-
-static inline int read(int fd, char *buf, off_t count)
-{
-       return sys_read(fd, buf, count);
-}
-
-static inline off_t lseek(int fd, off_t offset, int count)
-{
-       return sys_lseek(fd, offset, count);
-}
-
-static inline int dup(int fd)
-{
-       return sys_dup(fd);
-}
-
-static inline int execve(char *filename, char * argv [],
-       char * envp[])
-{
-       extern int __execve(char *, char **, char **, struct task_struct *);
-       return __execve(filename, argv, envp, current);
-}
-
-static inline int open(const char *file, int flag, int mode)
-{
-       return sys_open(file, flag, mode);
-}
-
-static inline int close(int fd)
-{
-       return sys_close(fd);
-}
-
-static inline void _exit(int exitcode)
-{
-       sys_exit(exitcode);
-}
-
-static inline pid_t waitpid(pid_t pid, int *wait_stat, int options)
-{
-       return sys_wait4(pid, wait_stat, options, NULL);
-}
-
-asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
-                               unsigned long prot, unsigned long flags,
-                               unsigned long fd, unsigned long offset);
-asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len,
-                               unsigned long prot, unsigned long flags,
-                               unsigned long fd, unsigned long pgoff);
-struct pt_regs;
-asmlinkage int sys_execve(struct pt_regs *regs);
-int sys_clone(unsigned long clone_flags, unsigned long usp,
-               struct pt_regs *regs);
-int sys_vfork(struct pt_regs *regs);
-int sys_pipe(int *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-                               const struct sigaction __user *act,
-                               struct sigaction __user *oact,
-                               size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 #endif /* __ASSEMBLY__ */
 
 #undef STR
index 77069df92bf8f05d80b9ca1e528622d4f6124a27..1022737f4f34884ea392264cd8a21156290bad67 100644 (file)
 
 #ifdef __KERNEL__
 
-#ifndef __ASSEMBLY__
+#include <asm/asm-compat.h>
 
 /* firmware feature bitmask values */
 #define FIRMWARE_MAX_FEATURES 63
 
-#define FW_FEATURE_PFT         (1UL<<0)
-#define FW_FEATURE_TCE         (1UL<<1)
-#define FW_FEATURE_SPRG0       (1UL<<2)
-#define FW_FEATURE_DABR                (1UL<<3)
-#define FW_FEATURE_COPY                (1UL<<4)
-#define FW_FEATURE_ASR         (1UL<<5)
-#define FW_FEATURE_DEBUG       (1UL<<6)
-#define FW_FEATURE_TERM                (1UL<<7)
-#define FW_FEATURE_PERF                (1UL<<8)
-#define FW_FEATURE_DUMP                (1UL<<9)
-#define FW_FEATURE_INTERRUPT   (1UL<<10)
-#define FW_FEATURE_MIGRATE     (1UL<<11)
-#define FW_FEATURE_PERFMON     (1UL<<12)
-#define FW_FEATURE_CRQ         (1UL<<13)
-#define FW_FEATURE_VIO         (1UL<<14)
-#define FW_FEATURE_RDMA                (1UL<<15)
-#define FW_FEATURE_LLAN                (1UL<<16)
-#define FW_FEATURE_BULK                (1UL<<17)
-#define FW_FEATURE_XDABR       (1UL<<18)
-#define FW_FEATURE_MULTITCE    (1UL<<19)
-#define FW_FEATURE_SPLPAR      (1UL<<20)
-#define FW_FEATURE_ISERIES     (1UL<<21)
-#define FW_FEATURE_LPAR                (1UL<<22)
+#define FW_FEATURE_PFT         ASM_CONST(0x0000000000000001)
+#define FW_FEATURE_TCE         ASM_CONST(0x0000000000000002)
+#define FW_FEATURE_SPRG0       ASM_CONST(0x0000000000000004)
+#define FW_FEATURE_DABR                ASM_CONST(0x0000000000000008)
+#define FW_FEATURE_COPY                ASM_CONST(0x0000000000000010)
+#define FW_FEATURE_ASR         ASM_CONST(0x0000000000000020)
+#define FW_FEATURE_DEBUG       ASM_CONST(0x0000000000000040)
+#define FW_FEATURE_TERM                ASM_CONST(0x0000000000000080)
+#define FW_FEATURE_PERF                ASM_CONST(0x0000000000000100)
+#define FW_FEATURE_DUMP                ASM_CONST(0x0000000000000200)
+#define FW_FEATURE_INTERRUPT   ASM_CONST(0x0000000000000400)
+#define FW_FEATURE_MIGRATE     ASM_CONST(0x0000000000000800)
+#define FW_FEATURE_PERFMON     ASM_CONST(0x0000000000001000)
+#define FW_FEATURE_CRQ         ASM_CONST(0x0000000000002000)
+#define FW_FEATURE_VIO         ASM_CONST(0x0000000000004000)
+#define FW_FEATURE_RDMA                ASM_CONST(0x0000000000008000)
+#define FW_FEATURE_LLAN                ASM_CONST(0x0000000000010000)
+#define FW_FEATURE_BULK                ASM_CONST(0x0000000000020000)
+#define FW_FEATURE_XDABR       ASM_CONST(0x0000000000040000)
+#define FW_FEATURE_MULTITCE    ASM_CONST(0x0000000000080000)
+#define FW_FEATURE_SPLPAR      ASM_CONST(0x0000000000100000)
+#define FW_FEATURE_ISERIES     ASM_CONST(0x0000000000200000)
+#define FW_FEATURE_LPAR                ASM_CONST(0x0000000000400000)
+
+#ifndef __ASSEMBLY__
 
 enum {
 #ifdef CONFIG_PPC64
@@ -94,6 +96,23 @@ extern void machine_check_fwnmi(void);
 /* This is true if we are using the firmware NMI handler (typically LPAR) */
 extern int fwnmi_active;
 
+#else /* __ASSEMBLY__ */
+
+#define BEGIN_FW_FTR_SECTION           96:
+
+#define END_FW_FTR_SECTION(msk, val)           \
+97:                                            \
+       .section __fw_ftr_fixup,"a";            \
+       .align 3;                               \
+       .llong msk;                             \
+       .llong val;                             \
+       .llong 96b;                             \
+       .llong 97b;                             \
+       .previous
+
+#define END_FW_FTR_SECTION_IFSET(msk)  END_FW_FTR_SECTION((msk), (msk))
+#define END_FW_FTR_SECTION_IFCLR(msk)  END_FW_FTR_SECTION((msk), 0)
+
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 #endif /* __ASM_POWERPC_FIRMWARE_H */
diff --git a/include/asm-powerpc/fs_pd.h b/include/asm-powerpc/fs_pd.h
new file mode 100644 (file)
index 0000000..3d0e819
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Platform information definitions.
+ *
+ * 2006 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef FS_PD_H
+#define FS_PD_H
+#include <asm/cpm2.h>
+#include <sysdev/fsl_soc.h>
+#include <asm/time.h>
+
+static inline int uart_baudrate(void)
+{
+        return get_baudrate();
+}
+
+static inline int uart_clock(void)
+{
+        return ppc_proc_freq;
+}
+
+#define cpm2_map(member)                                               \
+({                                                                     \
+       u32 offset = offsetof(cpm2_map_t, member);                      \
+       void *addr = ioremap (CPM_MAP_ADDR + offset,                    \
+                             sizeof( ((cpm2_map_t*)0)->member));       \
+       addr;                                                           \
+})
+
+#define cpm2_map_size(member, size)                                    \
+({                                                                     \
+       u32 offset = offsetof(cpm2_map_t, member);                      \
+       void *addr = ioremap (CPM_MAP_ADDR + offset, size);             \
+       addr;                                                           \
+})
+
+#define cpm2_unmap(addr)       iounmap(addr)
+
+#endif
diff --git a/include/asm-powerpc/immap_qe.h b/include/asm-powerpc/immap_qe.h
new file mode 100644 (file)
index 0000000..ce12f85
--- /dev/null
@@ -0,0 +1,477 @@
+/*
+ * include/asm-powerpc/immap_qe.h
+ *
+ * QUICC Engine (QE) Internal Memory Map.
+ * The Internal Memory Map for devices with QE on them. This
+ * is the superset of all QE devices (8360, etc.).
+
+ * Copyright (C) 2006. Freescale Semicondutor, Inc. All rights reserved.
+ *
+ * Authors:    Shlomi Gridish <gridish@freescale.com>
+ *             Li Yang <leoli@freescale.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#ifndef _ASM_POWERPC_IMMAP_QE_H
+#define _ASM_POWERPC_IMMAP_QE_H
+#ifdef __KERNEL__
+
+#include <linux/kernel.h>
+
+#define QE_IMMAP_SIZE  (1024 * 1024)   /* 1MB from 1MB+IMMR */
+
+/* QE I-RAM */
+struct qe_iram {
+       __be32  iadd;           /* I-RAM Address Register */
+       __be32  idata;          /* I-RAM Data Register */
+       u8      res0[0x78];
+} __attribute__ ((packed));
+
+/* QE Interrupt Controller */
+struct qe_ic_regs {
+       __be32  qicr;
+       __be32  qivec;
+       __be32  qripnr;
+       __be32  qipnr;
+       __be32  qipxcc;
+       __be32  qipycc;
+       __be32  qipwcc;
+       __be32  qipzcc;
+       __be32  qimr;
+       __be32  qrimr;
+       __be32  qicnr;
+       u8      res0[0x4];
+       __be32  qiprta;
+       __be32  qiprtb;
+       u8      res1[0x4];
+       __be32  qricr;
+       u8      res2[0x20];
+       __be32  qhivec;
+       u8      res3[0x1C];
+} __attribute__ ((packed));
+
+/* Communications Processor */
+struct cp_qe {
+       __be32  cecr;           /* QE command register */
+       __be32  ceccr;          /* QE controller configuration register */
+       __be32  cecdr;          /* QE command data register */
+       u8      res0[0xA];
+       __be16  ceter;          /* QE timer event register */
+       u8      res1[0x2];
+       __be16  cetmr;          /* QE timers mask register */
+       __be32  cetscr;         /* QE time-stamp timer control register */
+       __be32  cetsr1;         /* QE time-stamp register 1 */
+       __be32  cetsr2;         /* QE time-stamp register 2 */
+       u8      res2[0x8];
+       __be32  cevter;         /* QE virtual tasks event register */
+       __be32  cevtmr;         /* QE virtual tasks mask register */
+       __be16  cercr;          /* QE RAM control register */
+       u8      res3[0x2];
+       u8      res4[0x24];
+       __be16  ceexe1;         /* QE external request 1 event register */
+       u8      res5[0x2];
+       __be16  ceexm1;         /* QE external request 1 mask register */
+       u8      res6[0x2];
+       __be16  ceexe2;         /* QE external request 2 event register */
+       u8      res7[0x2];
+       __be16  ceexm2;         /* QE external request 2 mask register */
+       u8      res8[0x2];
+       __be16  ceexe3;         /* QE external request 3 event register */
+       u8      res9[0x2];
+       __be16  ceexm3;         /* QE external request 3 mask register */
+       u8      res10[0x2];
+       __be16  ceexe4;         /* QE external request 4 event register */
+       u8      res11[0x2];
+       __be16  ceexm4;         /* QE external request 4 mask register */
+       u8      res12[0x2];
+       u8      res13[0x280];
+} __attribute__ ((packed));
+
+/* QE Multiplexer */
+struct qe_mux {
+       __be32  cmxgcr;         /* CMX general clock route register */
+       __be32  cmxsi1cr_l;     /* CMX SI1 clock route low register */
+       __be32  cmxsi1cr_h;     /* CMX SI1 clock route high register */
+       __be32  cmxsi1syr;      /* CMX SI1 SYNC route register */
+       __be32  cmxucr1;        /* CMX UCC1, UCC3 clock route register */
+       __be32  cmxucr2;        /* CMX UCC5, UCC7 clock route register */
+       __be32  cmxucr3;        /* CMX UCC2, UCC4 clock route register */
+       __be32  cmxucr4;        /* CMX UCC6, UCC8 clock route register */
+       __be32  cmxupcr;        /* CMX UPC clock route register */
+       u8      res0[0x1C];
+} __attribute__ ((packed));
+
+/* QE Timers */
+struct qe_timers {
+       u8      gtcfr1;         /* Timer 1 and Timer 2 global config register*/
+       u8      res0[0x3];
+       u8      gtcfr2;         /* Timer 3 and timer 4 global config register*/
+       u8      res1[0xB];
+       __be16  gtmdr1;         /* Timer 1 mode register */
+       __be16  gtmdr2;         /* Timer 2 mode register */
+       __be16  gtrfr1;         /* Timer 1 reference register */
+       __be16  gtrfr2;         /* Timer 2 reference register */
+       __be16  gtcpr1;         /* Timer 1 capture register */
+       __be16  gtcpr2;         /* Timer 2 capture register */
+       __be16  gtcnr1;         /* Timer 1 counter */
+       __be16  gtcnr2;         /* Timer 2 counter */
+       __be16  gtmdr3;         /* Timer 3 mode register */
+       __be16  gtmdr4;         /* Timer 4 mode register */
+       __be16  gtrfr3;         /* Timer 3 reference register */
+       __be16  gtrfr4;         /* Timer 4 reference register */
+       __be16  gtcpr3;         /* Timer 3 capture register */
+       __be16  gtcpr4;         /* Timer 4 capture register */
+       __be16  gtcnr3;         /* Timer 3 counter */
+       __be16  gtcnr4;         /* Timer 4 counter */
+       __be16  gtevr1;         /* Timer 1 event register */
+       __be16  gtevr2;         /* Timer 2 event register */
+       __be16  gtevr3;         /* Timer 3 event register */
+       __be16  gtevr4;         /* Timer 4 event register */
+       __be16  gtps;           /* Timer 1 prescale register */
+       u8 res2[0x46];
+} __attribute__ ((packed));
+
+/* BRG */
+struct qe_brg {
+       __be32  brgc1;          /* BRG1 configuration register */
+       __be32  brgc2;          /* BRG2 configuration register */
+       __be32  brgc3;          /* BRG3 configuration register */
+       __be32  brgc4;          /* BRG4 configuration register */
+       __be32  brgc5;          /* BRG5 configuration register */
+       __be32  brgc6;          /* BRG6 configuration register */
+       __be32  brgc7;          /* BRG7 configuration register */
+       __be32  brgc8;          /* BRG8 configuration register */
+       __be32  brgc9;          /* BRG9 configuration register */
+       __be32  brgc10;         /* BRG10 configuration register */
+       __be32  brgc11;         /* BRG11 configuration register */
+       __be32  brgc12;         /* BRG12 configuration register */
+       __be32  brgc13;         /* BRG13 configuration register */
+       __be32  brgc14;         /* BRG14 configuration register */
+       __be32  brgc15;         /* BRG15 configuration register */
+       __be32  brgc16;         /* BRG16 configuration register */
+       u8      res0[0x40];
+} __attribute__ ((packed));
+
+/* SPI */
+struct spi {
+       u8      res0[0x20];
+       __be32  spmode;         /* SPI mode register */
+       u8      res1[0x2];
+       u8      spie;           /* SPI event register */
+       u8      res2[0x1];
+       u8      res3[0x2];
+       u8      spim;           /* SPI mask register */
+       u8      res4[0x1];
+       u8      res5[0x1];
+       u8      spcom;          /* SPI command register */
+       u8      res6[0x2];
+       __be32  spitd;          /* SPI transmit data register (cpu mode) */
+       __be32  spird;          /* SPI receive data register (cpu mode) */
+       u8      res7[0x8];
+} __attribute__ ((packed));
+
+/* SI */
+struct si1 {
+       __be16  siamr1;         /* SI1 TDMA mode register */
+       __be16  sibmr1;         /* SI1 TDMB mode register */
+       __be16  sicmr1;         /* SI1 TDMC mode register */
+       __be16  sidmr1;         /* SI1 TDMD mode register */
+       u8      siglmr1_h;      /* SI1 global mode register high */
+       u8      res0[0x1];
+       u8      sicmdr1_h;      /* SI1 command register high */
+       u8      res2[0x1];
+       u8      sistr1_h;       /* SI1 status register high */
+       u8      res3[0x1];
+       __be16  sirsr1_h;       /* SI1 RAM shadow address register high */
+       u8      sitarc1;        /* SI1 RAM counter Tx TDMA */
+       u8      sitbrc1;        /* SI1 RAM counter Tx TDMB */
+       u8      sitcrc1;        /* SI1 RAM counter Tx TDMC */
+       u8      sitdrc1;        /* SI1 RAM counter Tx TDMD */
+       u8      sirarc1;        /* SI1 RAM counter Rx TDMA */
+       u8      sirbrc1;        /* SI1 RAM counter Rx TDMB */
+       u8      sircrc1;        /* SI1 RAM counter Rx TDMC */
+       u8      sirdrc1;        /* SI1 RAM counter Rx TDMD */
+       u8      res4[0x8];
+       __be16  siemr1;         /* SI1 TDME mode register 16 bits */
+       __be16  sifmr1;         /* SI1 TDMF mode register 16 bits */
+       __be16  sigmr1;         /* SI1 TDMG mode register 16 bits */
+       __be16  sihmr1;         /* SI1 TDMH mode register 16 bits */
+       u8      siglmg1_l;      /* SI1 global mode register low 8 bits */
+       u8      res5[0x1];
+       u8      sicmdr1_l;      /* SI1 command register low 8 bits */
+       u8      res6[0x1];
+       u8      sistr1_l;       /* SI1 status register low 8 bits */
+       u8      res7[0x1];
+       __be16  sirsr1_l;       /* SI1 RAM shadow address register low 16 bits*/
+       u8      siterc1;        /* SI1 RAM counter Tx TDME 8 bits */
+       u8      sitfrc1;        /* SI1 RAM counter Tx TDMF 8 bits */
+       u8      sitgrc1;        /* SI1 RAM counter Tx TDMG 8 bits */
+       u8      sithrc1;        /* SI1 RAM counter Tx TDMH 8 bits */
+       u8      sirerc1;        /* SI1 RAM counter Rx TDME 8 bits */
+       u8      sirfrc1;        /* SI1 RAM counter Rx TDMF 8 bits */
+       u8      sirgrc1;        /* SI1 RAM counter Rx TDMG 8 bits */
+       u8      sirhrc1;        /* SI1 RAM counter Rx TDMH 8 bits */
+       u8      res8[0x8];
+       __be32  siml1;          /* SI1 multiframe limit register */
+       u8      siedm1;         /* SI1 extended diagnostic mode register */
+       u8      res9[0xBB];
+} __attribute__ ((packed));
+
+/* SI Routing Tables */
+struct sir {
+       u8      tx[0x400];
+       u8      rx[0x400];
+       u8      res0[0x800];
+} __attribute__ ((packed));
+
+/* USB Controller */
+struct usb_ctlr {
+       u8      usb_usmod;
+       u8      usb_usadr;
+       u8      usb_uscom;
+       u8      res1[1];
+       __be16  usb_usep1;
+       __be16  usb_usep2;
+       __be16  usb_usep3;
+       __be16  usb_usep4;
+       u8      res2[4];
+       __be16  usb_usber;
+       u8      res3[2];
+       __be16  usb_usbmr;
+       u8      res4[1];
+       u8      usb_usbs;
+       __be16  usb_ussft;
+       u8      res5[2];
+       __be16  usb_usfrn;
+       u8      res6[0x22];
+} __attribute__ ((packed));
+
+/* MCC */
+struct mcc {
+       __be32  mcce;           /* MCC event register */
+       __be32  mccm;           /* MCC mask register */
+       __be32  mccf;           /* MCC configuration register */
+       __be32  merl;           /* MCC emergency request level register */
+       u8      res0[0xF0];
+} __attribute__ ((packed));
+
+/* QE UCC Slow */
+struct ucc_slow {
+       __be32  gumr_l;         /* UCCx general mode register (low) */
+       __be32  gumr_h;         /* UCCx general mode register (high) */
+       __be16  upsmr;          /* UCCx protocol-specific mode register */
+       u8      res0[0x2];
+       __be16  utodr;          /* UCCx transmit on demand register */
+       __be16  udsr;           /* UCCx data synchronization register */
+       __be16  ucce;           /* UCCx event register */
+       u8      res1[0x2];
+       __be16  uccm;           /* UCCx mask register */
+       u8      res2[0x1];
+       u8      uccs;           /* UCCx status register */
+       u8      res3[0x24];
+       __be16  utpt;
+       u8      guemr;          /* UCC general extended mode register */
+       u8      res4[0x200 - 0x091];
+} __attribute__ ((packed));
+
+/* QE UCC Fast */
+struct ucc_fast {
+       __be32  gumr;           /* UCCx general mode register */
+       __be32  upsmr;          /* UCCx protocol-specific mode register */
+       __be16  utodr;          /* UCCx transmit on demand register */
+       u8      res0[0x2];
+       __be16  udsr;           /* UCCx data synchronization register */
+       u8      res1[0x2];
+       __be32  ucce;           /* UCCx event register */
+       __be32  uccm;           /* UCCx mask register */
+       u8      uccs;           /* UCCx status register */
+       u8      res2[0x7];
+       __be32  urfb;           /* UCC receive FIFO base */
+       __be16  urfs;           /* UCC receive FIFO size */
+       u8      res3[0x2];
+       __be16  urfet;          /* UCC receive FIFO emergency threshold */
+       __be16  urfset;         /* UCC receive FIFO special emergency
+                                  threshold */
+       __be32  utfb;           /* UCC transmit FIFO base */
+       __be16  utfs;           /* UCC transmit FIFO size */
+       u8      res4[0x2];
+       __be16  utfet;          /* UCC transmit FIFO emergency threshold */
+       u8      res5[0x2];
+       __be16  utftt;          /* UCC transmit FIFO transmit threshold */
+       u8      res6[0x2];
+       __be16  utpt;           /* UCC transmit polling timer */
+       u8      res7[0x2];
+       __be32  urtry;          /* UCC retry counter register */
+       u8      res8[0x4C];
+       u8      guemr;          /* UCC general extended mode register */
+       u8      res9[0x100 - 0x091];
+} __attribute__ ((packed));
+
+/* QE UCC */
+struct ucc_common {
+       u8      res1[0x90];
+       u8      guemr;
+       u8      res2[0x200 - 0x091];
+} __attribute__ ((packed));
+
+struct ucc {
+       union {
+               struct  ucc_slow slow;
+               struct  ucc_fast fast;
+               struct  ucc_common common;
+       };
+} __attribute__ ((packed));
+
+/* MultiPHY UTOPIA POS Controllers (UPC) */
+struct upc {
+       __be32  upgcr;          /* UTOPIA/POS general configuration register */
+       __be32  uplpa;          /* UTOPIA/POS last PHY address */
+       __be32  uphec;          /* ATM HEC register */
+       __be32  upuc;           /* UTOPIA/POS UCC configuration */
+       __be32  updc1;          /* UTOPIA/POS device 1 configuration */
+       __be32  updc2;          /* UTOPIA/POS device 2 configuration */
+       __be32  updc3;          /* UTOPIA/POS device 3 configuration */
+       __be32  updc4;          /* UTOPIA/POS device 4 configuration */
+       __be32  upstpa;         /* UTOPIA/POS STPA threshold */
+       u8      res0[0xC];
+       __be32  updrs1_h;       /* UTOPIA/POS device 1 rate select */
+       __be32  updrs1_l;       /* UTOPIA/POS device 1 rate select */
+       __be32  updrs2_h;       /* UTOPIA/POS device 2 rate select */
+       __be32  updrs2_l;       /* UTOPIA/POS device 2 rate select */
+       __be32  updrs3_h;       /* UTOPIA/POS device 3 rate select */
+       __be32  updrs3_l;       /* UTOPIA/POS device 3 rate select */
+       __be32  updrs4_h;       /* UTOPIA/POS device 4 rate select */
+       __be32  updrs4_l;       /* UTOPIA/POS device 4 rate select */
+       __be32  updrp1;         /* UTOPIA/POS device 1 receive priority low */
+       __be32  updrp2;         /* UTOPIA/POS device 2 receive priority low */
+       __be32  updrp3;         /* UTOPIA/POS device 3 receive priority low */
+       __be32  updrp4;         /* UTOPIA/POS device 4 receive priority low */
+       __be32  upde1;          /* UTOPIA/POS device 1 event */
+       __be32  upde2;          /* UTOPIA/POS device 2 event */
+       __be32  upde3;          /* UTOPIA/POS device 3 event */
+       __be32  upde4;          /* UTOPIA/POS device 4 event */
+       __be16  uprp1;
+       __be16  uprp2;
+       __be16  uprp3;
+       __be16  uprp4;
+       u8      res1[0x8];
+       __be16  uptirr1_0;      /* Device 1 transmit internal rate 0 */
+       __be16  uptirr1_1;      /* Device 1 transmit internal rate 1 */
+       __be16  uptirr1_2;      /* Device 1 transmit internal rate 2 */
+       __be16  uptirr1_3;      /* Device 1 transmit internal rate 3 */
+       __be16  uptirr2_0;      /* Device 2 transmit internal rate 0 */
+       __be16  uptirr2_1;      /* Device 2 transmit internal rate 1 */
+       __be16  uptirr2_2;      /* Device 2 transmit internal rate 2 */
+       __be16  uptirr2_3;      /* Device 2 transmit internal rate 3 */
+       __be16  uptirr3_0;      /* Device 3 transmit internal rate 0 */
+       __be16  uptirr3_1;      /* Device 3 transmit internal rate 1 */
+       __be16  uptirr3_2;      /* Device 3 transmit internal rate 2 */
+       __be16  uptirr3_3;      /* Device 3 transmit internal rate 3 */
+       __be16  uptirr4_0;      /* Device 4 transmit internal rate 0 */
+       __be16  uptirr4_1;      /* Device 4 transmit internal rate 1 */
+       __be16  uptirr4_2;      /* Device 4 transmit internal rate 2 */
+       __be16  uptirr4_3;      /* Device 4 transmit internal rate 3 */
+       __be32  uper1;          /* Device 1 port enable register */
+       __be32  uper2;          /* Device 2 port enable register */
+       __be32  uper3;          /* Device 3 port enable register */
+       __be32  uper4;          /* Device 4 port enable register */
+       u8      res2[0x150];
+} __attribute__ ((packed));
+
+/* SDMA */
+struct sdma {
+       __be32  sdsr;           /* Serial DMA status register */
+       __be32  sdmr;           /* Serial DMA mode register */
+       __be32  sdtr1;          /* SDMA system bus threshold register */
+       __be32  sdtr2;          /* SDMA secondary bus threshold register */
+       __be32  sdhy1;          /* SDMA system bus hysteresis register */
+       __be32  sdhy2;          /* SDMA secondary bus hysteresis register */
+       __be32  sdta1;          /* SDMA system bus address register */
+       __be32  sdta2;          /* SDMA secondary bus address register */
+       __be32  sdtm1;          /* SDMA system bus MSNUM register */
+       __be32  sdtm2;          /* SDMA secondary bus MSNUM register */
+       u8      res0[0x10];
+       __be32  sdaqr;          /* SDMA address bus qualify register */
+       __be32  sdaqmr;         /* SDMA address bus qualify mask register */
+       u8      res1[0x4];
+       __be32  sdebcr;         /* SDMA CAM entries base register */
+       u8      res2[0x38];
+} __attribute__ ((packed));
+
+/* Debug Space */
+struct dbg {
+       __be32  bpdcr;          /* Breakpoint debug command register */
+       __be32  bpdsr;          /* Breakpoint debug status register */
+       __be32  bpdmr;          /* Breakpoint debug mask register */
+       __be32  bprmrr0;        /* Breakpoint request mode risc register 0 */
+       __be32  bprmrr1;        /* Breakpoint request mode risc register 1 */
+       u8      res0[0x8];
+       __be32  bprmtr0;        /* Breakpoint request mode trb register 0 */
+       __be32  bprmtr1;        /* Breakpoint request mode trb register 1 */
+       u8      res1[0x8];
+       __be32  bprmir;         /* Breakpoint request mode immediate register */
+       __be32  bprmsr;         /* Breakpoint request mode serial register */
+       __be32  bpemr;          /* Breakpoint exit mode register */
+       u8      res2[0x48];
+} __attribute__ ((packed));
+
+/* RISC Special Registers (Trap and Breakpoint) */
+struct rsp {
+       u8      fixme[0x100];
+} __attribute__ ((packed));
+
+struct qe_immap {
+       struct qe_iram          iram;           /* I-RAM */
+       struct qe_ic_regs       ic;             /* Interrupt Controller */
+       struct cp_qe            cp;             /* Communications Processor */
+       struct qe_mux           qmx;            /* QE Multiplexer */
+       struct qe_timers        qet;            /* QE Timers */
+       struct spi              spi[0x2];       /* spi */
+       struct mcc              mcc;            /* mcc */
+       struct qe_brg           brg;            /* brg */
+       struct usb_ctlr         usb;            /* USB */
+       struct si1              si1;            /* SI */
+       u8                      res11[0x800];
+       struct sir              sir;            /* SI Routing Tables */
+       struct ucc              ucc1;           /* ucc1 */
+       struct ucc              ucc3;           /* ucc3 */
+       struct ucc              ucc5;           /* ucc5 */
+       struct ucc              ucc7;           /* ucc7 */
+       u8                      res12[0x600];
+       struct upc              upc1;           /* MultiPHY UTOPIA POS Ctrlr 1*/
+       struct ucc              ucc2;           /* ucc2 */
+       struct ucc              ucc4;           /* ucc4 */
+       struct ucc              ucc6;           /* ucc6 */
+       struct ucc              ucc8;           /* ucc8 */
+       u8                      res13[0x600];
+       struct upc              upc2;           /* MultiPHY UTOPIA POS Ctrlr 2*/
+       struct sdma             sdma;           /* SDMA */
+       struct dbg              dbg;            /* Debug Space */
+       struct rsp              rsp[0x2];       /* RISC Special Registers
+                                                  (Trap and Breakpoint) */
+       u8                      res14[0x300];
+       u8                      res15[0x3A00];
+       u8                      res16[0x8000];  /* 0x108000 - 0x110000 */
+       u8                      muram[0xC000];  /* 0x110000 - 0x11C000
+                                                  Multi-user RAM */
+       u8                      res17[0x24000]; /* 0x11C000 - 0x140000 */
+       u8                      res18[0xC0000]; /* 0x140000 - 0x200000 */
+} __attribute__ ((packed));
+
+extern struct qe_immap *qe_immr;
+extern phys_addr_t get_qe_base(void);
+
+static inline unsigned long immrbar_virt_to_phys(volatile void * address)
+{
+       if ( ((u32)address >= (u32)qe_immr) &&
+                       ((u32)address < ((u32)qe_immr + QE_IMMAP_SIZE)) )
+               return (unsigned long)(address - (u32)qe_immr +
+                               (u32)get_qe_base());
+       return (unsigned long)virt_to_phys(address);
+}
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_IMMAP_QE_H */
index 19b2ec1ec665c4b016525c5147851f7943c8f2ca..cbbd8c648df1341120e825b29c9d33a9763d234b 100644 (file)
@@ -11,7 +11,6 @@
 
 /* Check of existence of legacy devices */
 extern int check_legacy_ioport(unsigned long base_port);
-#define PARALLEL_BASE  0x378
 #define PNPBIOS_BASE   0xf000  /* only relevant for PReP */
 
 #ifndef CONFIG_PPC64
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 34e1f89a5fa02eda188e2654e47dda3555066686..2dafa376a63f60f89b3697a2034c943583a1de87 100644 (file)
@@ -44,6 +44,28 @@ typedef unsigned int kprobe_opcode_t;
 #define IS_TDI(instr)          (((instr) & 0xfc000000) == 0x08000000)
 #define IS_TWI(instr)          (((instr) & 0xfc000000) == 0x0c000000)
 
+/*
+ * 64bit powerpc uses function descriptors.
+ * Handle cases where:
+ *             - User passes a <.symbol> or <module:.symbol>
+ *             - User passes a <symbol> or <module:symbol>
+ *             - User passes a non-existant symbol, kallsyms_lookup_name
+ *               returns 0. Don't deref the NULL pointer in that case
+ */
+#define kprobe_lookup_name(name, addr)                                 \
+{                                                                      \
+       addr = (kprobe_opcode_t *)kallsyms_lookup_name(name);           \
+       if (addr) {                                                     \
+               char *colon;                                            \
+               if ((colon = strchr(name, ':')) != NULL) {              \
+                       colon++;                                        \
+                       if (*colon != '\0' && *colon != '.')            \
+                               addr = *(kprobe_opcode_t **)addr;       \
+               } else if (name[0] != '.')                              \
+                       addr = *(kprobe_opcode_t **)addr;               \
+       }                                                               \
+}
+
 #define JPROBE_ENTRY(pentry)   (kprobe_opcode_t *)((func_descr_t *)pentry)
 
 #define is_trap(instr) (IS_TW(instr) || IS_TD(instr) || \
diff --git a/include/asm-powerpc/mpc85xx.h b/include/asm-powerpc/mpc85xx.h
new file mode 100644 (file)
index 0000000..ccdb8a2
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * include/asm-powerpc/mpc85xx.h
+ *
+ * MPC85xx definitions
+ *
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
+ *
+ * Copyright 2004 Freescale Semiconductor, Inc
+ *
+ * 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.
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_MPC85xx_H__
+#define __ASM_MPC85xx_H__
+
+#include <asm/mmu.h>
+
+#ifdef CONFIG_85xx
+
+#if defined(CONFIG_MPC8540_ADS) || defined(CONFIG_MPC8560_ADS)
+#include <platforms/85xx/mpc85xx_ads.h>
+#endif
+#if defined(CONFIG_MPC8555_CDS) || defined(CONFIG_MPC8548_CDS)
+#include <platforms/85xx/mpc8555_cds.h>
+#endif
+#ifdef CONFIG_MPC85xx_CDS
+#include <platforms/85xx/mpc85xx_cds.h>
+#endif
+
+#define _IO_BASE        isa_io_base
+#define _ISA_MEM_BASE   isa_mem_base
+#ifdef CONFIG_PCI
+#define PCI_DRAM_OFFSET pci_dram_offset
+#else
+#define PCI_DRAM_OFFSET 0
+#endif
+
+/* Let modules/drivers get at CCSRBAR */
+extern phys_addr_t get_ccsrbar(void);
+
+#ifdef MODULE
+#define CCSRBAR get_ccsrbar()
+#else
+#define CCSRBAR BOARD_CCSRBAR
+#endif
+
+#endif /* CONFIG_85xx */
+#endif /* __ASM_MPC85xx_H__ */
+#endif /* __KERNEL__ */
index 4435efe85d0edb37cd2d3de5b0307140cb8375b1..4ad77a13f8652ebdf69aa2225ceea03346916212 100644 (file)
@@ -73,6 +73,8 @@ struct pt_regs {
 #ifndef __ASSEMBLY__
 
 #define instruction_pointer(regs) ((regs)->nip)
+#define regs_return_value(regs) ((regs)->gpr[3])
+
 #ifdef CONFIG_SMP
 extern unsigned long profile_pc(struct pt_regs *regs);
 #else
diff --git a/include/asm-powerpc/qe.h b/include/asm-powerpc/qe.h
new file mode 100644 (file)
index 0000000..a62168e
--- /dev/null
@@ -0,0 +1,457 @@
+/*
+ * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
+ *
+ * Authors:    Shlomi Gridish <gridish@freescale.com>
+ *             Li Yang <leoli@freescale.com>
+ *
+ * Description:
+ * QUICC Engine (QE) external definitions and structure.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#ifndef _ASM_POWERPC_QE_H
+#define _ASM_POWERPC_QE_H
+#ifdef __KERNEL__
+
+#include <asm/immap_qe.h>
+
+#define QE_NUM_OF_SNUM 28
+#define QE_NUM_OF_BRGS 16
+#define QE_NUM_OF_PORTS        1024
+
+/* Memory partitions
+*/
+#define MEM_PART_SYSTEM                0
+#define MEM_PART_SECONDARY     1
+#define MEM_PART_MURAM         2
+
+/* Export QE common operations */
+extern void qe_reset(void);
+extern int par_io_init(struct device_node *np);
+extern int par_io_of_config(struct device_node *np);
+
+/* QE internal API */
+int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input);
+void qe_setbrg(u32 brg, u32 rate);
+int qe_get_snum(void);
+void qe_put_snum(u8 snum);
+u32 qe_muram_alloc(u32 size, u32 align);
+int qe_muram_free(u32 offset);
+u32 qe_muram_alloc_fixed(u32 offset, u32 size);
+void qe_muram_dump(void);
+void *qe_muram_addr(u32 offset);
+
+/* Buffer descriptors */
+struct qe_bd {
+       u16 status;
+       u16 length;
+       u32 buf;
+} __attribute__ ((packed));
+
+#define BD_STATUS_MASK 0xffff0000
+#define BD_LENGTH_MASK 0x0000ffff
+
+/* Alignment */
+#define QE_INTR_TABLE_ALIGN    16      /* ??? */
+#define QE_ALIGNMENT_OF_BD     8
+#define QE_ALIGNMENT_OF_PRAM   64
+
+/* RISC allocation */
+enum qe_risc_allocation {
+       QE_RISC_ALLOCATION_RISC1 = 1,   /* RISC 1 */
+       QE_RISC_ALLOCATION_RISC2 = 2,   /* RISC 2 */
+       QE_RISC_ALLOCATION_RISC1_AND_RISC2 = 3  /* Dynamically choose
+                                                  RISC 1 or RISC 2 */
+};
+
+/* QE extended filtering Table Lookup Key Size */
+enum qe_fltr_tbl_lookup_key_size {
+       QE_FLTR_TABLE_LOOKUP_KEY_SIZE_8_BYTES
+               = 0x3f,         /* LookupKey parsed by the Generate LookupKey
+                                  CMD is truncated to 8 bytes */
+       QE_FLTR_TABLE_LOOKUP_KEY_SIZE_16_BYTES
+               = 0x5f,         /* LookupKey parsed by the Generate LookupKey
+                                  CMD is truncated to 16 bytes */
+};
+
+/* QE FLTR extended filtering Largest External Table Lookup Key Size */
+enum qe_fltr_largest_external_tbl_lookup_key_size {
+       QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_NONE
+               = 0x0,/* not used */
+       QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_8_BYTES
+               = QE_FLTR_TABLE_LOOKUP_KEY_SIZE_8_BYTES,        /* 8 bytes */
+       QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_16_BYTES
+               = QE_FLTR_TABLE_LOOKUP_KEY_SIZE_16_BYTES,       /* 16 bytes */
+};
+
+/* structure representing QE parameter RAM */
+struct qe_timer_tables {
+       u16 tm_base;            /* QE timer table base adr */
+       u16 tm_ptr;             /* QE timer table pointer */
+       u16 r_tmr;              /* QE timer mode register */
+       u16 r_tmv;              /* QE timer valid register */
+       u32 tm_cmd;             /* QE timer cmd register */
+       u32 tm_cnt;             /* QE timer internal cnt */
+} __attribute__ ((packed));
+
+#define QE_FLTR_TAD_SIZE       8
+
+/* QE extended filtering Termination Action Descriptor (TAD) */
+struct qe_fltr_tad {
+       u8 serialized[QE_FLTR_TAD_SIZE];
+} __attribute__ ((packed));
+
+/* Communication Direction */
+enum comm_dir {
+       COMM_DIR_NONE = 0,
+       COMM_DIR_RX = 1,
+       COMM_DIR_TX = 2,
+       COMM_DIR_RX_AND_TX = 3
+};
+
+/* Clocks and BRGs */
+enum qe_clock {
+       QE_CLK_NONE = 0,
+       QE_BRG1,                /* Baud Rate Generator 1 */
+       QE_BRG2,                /* Baud Rate Generator 2 */
+       QE_BRG3,                /* Baud Rate Generator 3 */
+       QE_BRG4,                /* Baud Rate Generator 4 */
+       QE_BRG5,                /* Baud Rate Generator 5 */
+       QE_BRG6,                /* Baud Rate Generator 6 */
+       QE_BRG7,                /* Baud Rate Generator 7 */
+       QE_BRG8,                /* Baud Rate Generator 8 */
+       QE_BRG9,                /* Baud Rate Generator 9 */
+       QE_BRG10,               /* Baud Rate Generator 10 */
+       QE_BRG11,               /* Baud Rate Generator 11 */
+       QE_BRG12,               /* Baud Rate Generator 12 */
+       QE_BRG13,               /* Baud Rate Generator 13 */
+       QE_BRG14,               /* Baud Rate Generator 14 */
+       QE_BRG15,               /* Baud Rate Generator 15 */
+       QE_BRG16,               /* Baud Rate Generator 16 */
+       QE_CLK1,                /* Clock 1 */
+       QE_CLK2,                /* Clock 2 */
+       QE_CLK3,                /* Clock 3 */
+       QE_CLK4,                /* Clock 4 */
+       QE_CLK5,                /* Clock 5 */
+       QE_CLK6,                /* Clock 6 */
+       QE_CLK7,                /* Clock 7 */
+       QE_CLK8,                /* Clock 8 */
+       QE_CLK9,                /* Clock 9 */
+       QE_CLK10,               /* Clock 10 */
+       QE_CLK11,               /* Clock 11 */
+       QE_CLK12,               /* Clock 12 */
+       QE_CLK13,               /* Clock 13 */
+       QE_CLK14,               /* Clock 14 */
+       QE_CLK15,               /* Clock 15 */
+       QE_CLK16,               /* Clock 16 */
+       QE_CLK17,               /* Clock 17 */
+       QE_CLK18,               /* Clock 18 */
+       QE_CLK19,               /* Clock 19 */
+       QE_CLK20,               /* Clock 20 */
+       QE_CLK21,               /* Clock 21 */
+       QE_CLK22,               /* Clock 22 */
+       QE_CLK23,               /* Clock 23 */
+       QE_CLK24,               /* Clock 24 */
+       QE_CLK_DUMMY,
+};
+
+/* QE CMXUCR Registers.
+ * There are two UCCs represented in each of the four CMXUCR registers.
+ * These values are for the UCC in the LSBs
+ */
+#define QE_CMXUCR_MII_ENET_MNG         0x00007000
+#define QE_CMXUCR_MII_ENET_MNG_SHIFT   12
+#define QE_CMXUCR_GRANT                        0x00008000
+#define QE_CMXUCR_TSA                  0x00004000
+#define QE_CMXUCR_BKPT                 0x00000100
+#define QE_CMXUCR_TX_CLK_SRC_MASK      0x0000000F
+
+/* QE CMXGCR Registers.
+*/
+#define QE_CMXGCR_MII_ENET_MNG         0x00007000
+#define QE_CMXGCR_MII_ENET_MNG_SHIFT   12
+#define QE_CMXGCR_USBCS                        0x0000000f
+
+/* QE CECR Commands.
+*/
+#define QE_CR_FLG                      0x00010000
+#define QE_RESET                       0x80000000
+#define QE_INIT_TX_RX                  0x00000000
+#define QE_INIT_RX                     0x00000001
+#define QE_INIT_TX                     0x00000002
+#define QE_ENTER_HUNT_MODE             0x00000003
+#define QE_STOP_TX                     0x00000004
+#define QE_GRACEFUL_STOP_TX            0x00000005
+#define QE_RESTART_TX                  0x00000006
+#define QE_CLOSE_RX_BD                 0x00000007
+#define QE_SWITCH_COMMAND              0x00000007
+#define QE_SET_GROUP_ADDRESS           0x00000008
+#define QE_START_IDMA                  0x00000009
+#define QE_MCC_STOP_RX                 0x00000009
+#define QE_ATM_TRANSMIT                        0x0000000a
+#define QE_HPAC_CLEAR_ALL              0x0000000b
+#define QE_GRACEFUL_STOP_RX            0x0000001a
+#define QE_RESTART_RX                  0x0000001b
+#define QE_HPAC_SET_PRIORITY           0x0000010b
+#define QE_HPAC_STOP_TX                        0x0000020b
+#define QE_HPAC_STOP_RX                        0x0000030b
+#define QE_HPAC_GRACEFUL_STOP_TX       0x0000040b
+#define QE_HPAC_GRACEFUL_STOP_RX       0x0000050b
+#define QE_HPAC_START_TX               0x0000060b
+#define QE_HPAC_START_RX               0x0000070b
+#define QE_USB_STOP_TX                 0x0000000a
+#define QE_USB_RESTART_TX              0x0000000b
+#define QE_QMC_STOP_TX                 0x0000000c
+#define QE_QMC_STOP_RX                 0x0000000d
+#define QE_SS7_SU_FIL_RESET            0x0000000e
+/* jonathbr added from here down for 83xx */
+#define QE_RESET_BCS                   0x0000000a
+#define QE_MCC_INIT_TX_RX_16           0x00000003
+#define QE_MCC_STOP_TX                 0x00000004
+#define QE_MCC_INIT_TX_1               0x00000005
+#define QE_MCC_INIT_RX_1               0x00000006
+#define QE_MCC_RESET                   0x00000007
+#define QE_SET_TIMER                   0x00000008
+#define QE_RANDOM_NUMBER               0x0000000c
+#define QE_ATM_MULTI_THREAD_INIT       0x00000011
+#define QE_ASSIGN_PAGE                 0x00000012
+#define QE_ADD_REMOVE_HASH_ENTRY       0x00000013
+#define QE_START_FLOW_CONTROL          0x00000014
+#define QE_STOP_FLOW_CONTROL           0x00000015
+#define QE_ASSIGN_PAGE_TO_DEVICE       0x00000016
+
+#define QE_ASSIGN_RISC                 0x00000010
+#define QE_CR_MCN_NORMAL_SHIFT         6
+#define QE_CR_MCN_USB_SHIFT            4
+#define QE_CR_MCN_RISC_ASSIGN_SHIFT    8
+#define QE_CR_SNUM_SHIFT               17
+
+/* QE CECR Sub Block - sub block of QE command.
+*/
+#define QE_CR_SUBBLOCK_INVALID         0x00000000
+#define QE_CR_SUBBLOCK_USB             0x03200000
+#define QE_CR_SUBBLOCK_UCCFAST1                0x02000000
+#define QE_CR_SUBBLOCK_UCCFAST2                0x02200000
+#define QE_CR_SUBBLOCK_UCCFAST3                0x02400000
+#define QE_CR_SUBBLOCK_UCCFAST4                0x02600000
+#define QE_CR_SUBBLOCK_UCCFAST5                0x02800000
+#define QE_CR_SUBBLOCK_UCCFAST6                0x02a00000
+#define QE_CR_SUBBLOCK_UCCFAST7                0x02c00000
+#define QE_CR_SUBBLOCK_UCCFAST8                0x02e00000
+#define QE_CR_SUBBLOCK_UCCSLOW1                0x00000000
+#define QE_CR_SUBBLOCK_UCCSLOW2                0x00200000
+#define QE_CR_SUBBLOCK_UCCSLOW3                0x00400000
+#define QE_CR_SUBBLOCK_UCCSLOW4                0x00600000
+#define QE_CR_SUBBLOCK_UCCSLOW5                0x00800000
+#define QE_CR_SUBBLOCK_UCCSLOW6                0x00a00000
+#define QE_CR_SUBBLOCK_UCCSLOW7                0x00c00000
+#define QE_CR_SUBBLOCK_UCCSLOW8                0x00e00000
+#define QE_CR_SUBBLOCK_MCC1            0x03800000
+#define QE_CR_SUBBLOCK_MCC2            0x03a00000
+#define QE_CR_SUBBLOCK_MCC3            0x03000000
+#define QE_CR_SUBBLOCK_IDMA1           0x02800000
+#define QE_CR_SUBBLOCK_IDMA2           0x02a00000
+#define QE_CR_SUBBLOCK_IDMA3           0x02c00000
+#define QE_CR_SUBBLOCK_IDMA4           0x02e00000
+#define QE_CR_SUBBLOCK_HPAC            0x01e00000
+#define QE_CR_SUBBLOCK_SPI1            0x01400000
+#define QE_CR_SUBBLOCK_SPI2            0x01600000
+#define QE_CR_SUBBLOCK_RAND            0x01c00000
+#define QE_CR_SUBBLOCK_TIMER           0x01e00000
+#define QE_CR_SUBBLOCK_GENERAL         0x03c00000
+
+/* QE CECR Protocol - For non-MCC, specifies mode for QE CECR command */
+#define QE_CR_PROTOCOL_UNSPECIFIED     0x00    /* For all other protocols */
+#define QE_CR_PROTOCOL_HDLC_TRANSPARENT        0x00
+#define QE_CR_PROTOCOL_ATM_POS         0x0A
+#define QE_CR_PROTOCOL_ETHERNET                0x0C
+#define QE_CR_PROTOCOL_L2_SWITCH       0x0D
+
+/* BMR byte order */
+#define QE_BMR_BYTE_ORDER_BO_PPC       0x08    /* powerpc little endian */
+#define QE_BMR_BYTE_ORDER_BO_MOT       0x10    /* motorola big endian */
+#define QE_BMR_BYTE_ORDER_BO_MAX       0x18
+
+/* BRG configuration register */
+#define QE_BRGC_ENABLE         0x00010000
+#define QE_BRGC_DIVISOR_SHIFT  1
+#define QE_BRGC_DIVISOR_MAX    0xFFF
+#define QE_BRGC_DIV16          1
+
+/* QE Timers registers */
+#define QE_GTCFR1_PCAS 0x80
+#define QE_GTCFR1_STP2 0x20
+#define QE_GTCFR1_RST2 0x10
+#define QE_GTCFR1_GM2  0x08
+#define QE_GTCFR1_GM1  0x04
+#define QE_GTCFR1_STP1 0x02
+#define QE_GTCFR1_RST1 0x01
+
+/* SDMA registers */
+#define QE_SDSR_BER1   0x02000000
+#define QE_SDSR_BER2   0x01000000
+
+#define QE_SDMR_GLB_1_MSK      0x80000000
+#define QE_SDMR_ADR_SEL                0x20000000
+#define QE_SDMR_BER1_MSK       0x02000000
+#define QE_SDMR_BER2_MSK       0x01000000
+#define QE_SDMR_EB1_MSK                0x00800000
+#define QE_SDMR_ER1_MSK                0x00080000
+#define QE_SDMR_ER2_MSK                0x00040000
+#define QE_SDMR_CEN_MASK       0x0000E000
+#define QE_SDMR_SBER_1         0x00000200
+#define QE_SDMR_SBER_2         0x00000200
+#define QE_SDMR_EB1_PR_MASK    0x000000C0
+#define QE_SDMR_ER1_PR         0x00000008
+
+#define QE_SDMR_CEN_SHIFT      13
+#define QE_SDMR_EB1_PR_SHIFT   6
+
+#define QE_SDTM_MSNUM_SHIFT    24
+
+#define QE_SDEBCR_BA_MASK      0x01FFFFFF
+
+/* UPC */
+#define UPGCR_PROTOCOL 0x80000000      /* protocol ul2 or pl2 */
+#define UPGCR_TMS      0x40000000      /* Transmit master/slave mode */
+#define UPGCR_RMS      0x20000000      /* Receive master/slave mode */
+#define UPGCR_ADDR     0x10000000      /* Master MPHY Addr multiplexing */
+#define UPGCR_DIAG     0x01000000      /* Diagnostic mode */
+
+/* UCC */
+#define UCC_GUEMR_MODE_MASK_RX 0x02
+#define UCC_GUEMR_MODE_MASK_TX 0x01
+#define UCC_GUEMR_MODE_FAST_RX 0x02
+#define UCC_GUEMR_MODE_FAST_TX 0x01
+#define UCC_GUEMR_MODE_SLOW_RX 0x00
+#define UCC_GUEMR_MODE_SLOW_TX 0x00
+#define UCC_GUEMR_SET_RESERVED3        0x10    /* Bit 3 in the guemr is reserved but
+                                          must be set 1 */
+
+/* structure representing UCC SLOW parameter RAM */
+struct ucc_slow_pram {
+       u16 rbase;              /* RX BD base address */
+       u16 tbase;              /* TX BD base address */
+       u8 rfcr;                /* Rx function code */
+       u8 tfcr;                /* Tx function code */
+       u16 mrblr;              /* Rx buffer length */
+       u32 rstate;             /* Rx internal state */
+       u32 rptr;               /* Rx internal data pointer */
+       u16 rbptr;              /* rb BD Pointer */
+       u16 rcount;             /* Rx internal byte count */
+       u32 rtemp;              /* Rx temp */
+       u32 tstate;             /* Tx internal state */
+       u32 tptr;               /* Tx internal data pointer */
+       u16 tbptr;              /* Tx BD pointer */
+       u16 tcount;             /* Tx byte count */
+       u32 ttemp;              /* Tx temp */
+       u32 rcrc;               /* temp receive CRC */
+       u32 tcrc;               /* temp transmit CRC */
+} __attribute__ ((packed));
+
+/* General UCC SLOW Mode Register (GUMRH & GUMRL) */
+#define UCC_SLOW_GUMR_H_CRC16          0x00004000
+#define UCC_SLOW_GUMR_H_CRC16CCITT     0x00000000
+#define UCC_SLOW_GUMR_H_CRC32CCITT     0x00008000
+#define UCC_SLOW_GUMR_H_REVD           0x00002000
+#define UCC_SLOW_GUMR_H_TRX            0x00001000
+#define UCC_SLOW_GUMR_H_TTX            0x00000800
+#define UCC_SLOW_GUMR_H_CDP            0x00000400
+#define UCC_SLOW_GUMR_H_CTSP           0x00000200
+#define UCC_SLOW_GUMR_H_CDS            0x00000100
+#define UCC_SLOW_GUMR_H_CTSS           0x00000080
+#define UCC_SLOW_GUMR_H_TFL            0x00000040
+#define UCC_SLOW_GUMR_H_RFW            0x00000020
+#define UCC_SLOW_GUMR_H_TXSY           0x00000010
+#define UCC_SLOW_GUMR_H_4SYNC          0x00000004
+#define UCC_SLOW_GUMR_H_8SYNC          0x00000008
+#define UCC_SLOW_GUMR_H_16SYNC         0x0000000c
+#define UCC_SLOW_GUMR_H_RTSM           0x00000002
+#define UCC_SLOW_GUMR_H_RSYN           0x00000001
+
+#define UCC_SLOW_GUMR_L_TCI            0x10000000
+#define UCC_SLOW_GUMR_L_RINV           0x02000000
+#define UCC_SLOW_GUMR_L_TINV           0x01000000
+#define UCC_SLOW_GUMR_L_TEND           0x00020000
+#define UCC_SLOW_GUMR_L_ENR            0x00000020
+#define UCC_SLOW_GUMR_L_ENT            0x00000010
+
+/* General UCC FAST Mode Register */
+#define UCC_FAST_GUMR_TCI      0x20000000
+#define UCC_FAST_GUMR_TRX      0x10000000
+#define UCC_FAST_GUMR_TTX      0x08000000
+#define UCC_FAST_GUMR_CDP      0x04000000
+#define UCC_FAST_GUMR_CTSP     0x02000000
+#define UCC_FAST_GUMR_CDS      0x01000000
+#define UCC_FAST_GUMR_CTSS     0x00800000
+#define UCC_FAST_GUMR_TXSY     0x00020000
+#define UCC_FAST_GUMR_RSYN     0x00010000
+#define UCC_FAST_GUMR_RTSM     0x00002000
+#define UCC_FAST_GUMR_REVD     0x00000400
+#define UCC_FAST_GUMR_ENR      0x00000020
+#define UCC_FAST_GUMR_ENT      0x00000010
+
+/* Slow UCC Event Register (UCCE) */
+#define UCC_SLOW_UCCE_GLR      0x1000
+#define UCC_SLOW_UCCE_GLT      0x0800
+#define UCC_SLOW_UCCE_DCC      0x0400
+#define UCC_SLOW_UCCE_FLG      0x0200
+#define UCC_SLOW_UCCE_AB       0x0200
+#define UCC_SLOW_UCCE_IDLE     0x0100
+#define UCC_SLOW_UCCE_GRA      0x0080
+#define UCC_SLOW_UCCE_TXE      0x0010
+#define UCC_SLOW_UCCE_RXF      0x0008
+#define UCC_SLOW_UCCE_CCR      0x0008
+#define UCC_SLOW_UCCE_RCH      0x0008
+#define UCC_SLOW_UCCE_BSY      0x0004
+#define UCC_SLOW_UCCE_TXB      0x0002
+#define UCC_SLOW_UCCE_TX       0x0002
+#define UCC_SLOW_UCCE_RX       0x0001
+#define UCC_SLOW_UCCE_GOV      0x0001
+#define UCC_SLOW_UCCE_GUN      0x0002
+#define UCC_SLOW_UCCE_GINT     0x0004
+#define UCC_SLOW_UCCE_IQOV     0x0008
+
+#define UCC_SLOW_UCCE_HDLC_SET (UCC_SLOW_UCCE_TXE | UCC_SLOW_UCCE_BSY | \
+               UCC_SLOW_UCCE_GRA | UCC_SLOW_UCCE_TXB | UCC_SLOW_UCCE_RXF | \
+               UCC_SLOW_UCCE_DCC | UCC_SLOW_UCCE_GLT | UCC_SLOW_UCCE_GLR)
+#define UCC_SLOW_UCCE_ENET_SET (UCC_SLOW_UCCE_TXE | UCC_SLOW_UCCE_BSY | \
+               UCC_SLOW_UCCE_GRA | UCC_SLOW_UCCE_TXB | UCC_SLOW_UCCE_RXF)
+#define UCC_SLOW_UCCE_TRANS_SET        (UCC_SLOW_UCCE_TXE | UCC_SLOW_UCCE_BSY | \
+               UCC_SLOW_UCCE_GRA | UCC_SLOW_UCCE_TX | UCC_SLOW_UCCE_RX | \
+               UCC_SLOW_UCCE_DCC | UCC_SLOW_UCCE_GLT | UCC_SLOW_UCCE_GLR)
+#define UCC_SLOW_UCCE_UART_SET (UCC_SLOW_UCCE_BSY | UCC_SLOW_UCCE_GRA | \
+               UCC_SLOW_UCCE_TXB | UCC_SLOW_UCCE_TX | UCC_SLOW_UCCE_RX | \
+               UCC_SLOW_UCCE_GLT | UCC_SLOW_UCCE_GLR)
+#define UCC_SLOW_UCCE_QMC_SET  (UCC_SLOW_UCCE_IQOV | UCC_SLOW_UCCE_GINT | \
+               UCC_SLOW_UCCE_GUN | UCC_SLOW_UCCE_GOV)
+
+#define UCC_SLOW_UCCE_OTHER    (UCC_SLOW_UCCE_TXE | UCC_SLOW_UCCE_BSY | \
+               UCC_SLOW_UCCE_GRA | UCC_SLOW_UCCE_DCC | UCC_SLOW_UCCE_GLT | \
+               UCC_SLOW_UCCE_GLR)
+
+#define UCC_SLOW_INTR_TX       UCC_SLOW_UCCE_TXB
+#define UCC_SLOW_INTR_RX       (UCC_SLOW_UCCE_RXF | UCC_SLOW_UCCE_RX)
+#define UCC_SLOW_INTR          (UCC_SLOW_INTR_TX | UCC_SLOW_INTR_RX)
+
+/* UCC Transmit On Demand Register (UTODR) */
+#define UCC_SLOW_TOD   0x8000
+#define UCC_FAST_TOD   0x8000
+
+/* Function code masks */
+#define FC_GBL                         0x20
+#define FC_DTB_LCL                     0x02
+#define UCC_FAST_FUNCTION_CODE_GBL     0x20
+#define UCC_FAST_FUNCTION_CODE_DTB_LCL 0x02
+#define UCC_FAST_FUNCTION_CODE_BDB_LCL 0x01
+
+static inline long IS_MURAM_ERR(const u32 offset)
+{
+       return offset > (u32) - 1000L;
+}
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_QE_H */
diff --git a/include/asm-powerpc/qe_ic.h b/include/asm-powerpc/qe_ic.h
new file mode 100644 (file)
index 0000000..e386fb7
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * include/asm-powerpc/qe_ic.h
+ *
+ * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
+ *
+ * Authors:    Shlomi Gridish <gridish@freescale.com>
+ *             Li Yang <leoli@freescale.com>
+ *
+ * Description:
+ * QE IC external definitions and structure.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#ifndef _ASM_POWERPC_QE_IC_H
+#define _ASM_POWERPC_QE_IC_H
+
+#include <linux/irq.h>
+
+#define NUM_OF_QE_IC_GROUPS    6
+
+/* Flags when we init the QE IC */
+#define QE_IC_SPREADMODE_GRP_W                 0x00000001
+#define QE_IC_SPREADMODE_GRP_X                 0x00000002
+#define QE_IC_SPREADMODE_GRP_Y                 0x00000004
+#define QE_IC_SPREADMODE_GRP_Z                 0x00000008
+#define QE_IC_SPREADMODE_GRP_RISCA             0x00000010
+#define QE_IC_SPREADMODE_GRP_RISCB             0x00000020
+
+#define QE_IC_LOW_SIGNAL                       0x00000100
+#define QE_IC_HIGH_SIGNAL                      0x00000200
+
+#define QE_IC_GRP_W_PRI0_DEST_SIGNAL_HIGH      0x00001000
+#define QE_IC_GRP_W_PRI1_DEST_SIGNAL_HIGH      0x00002000
+#define QE_IC_GRP_X_PRI0_DEST_SIGNAL_HIGH      0x00004000
+#define QE_IC_GRP_X_PRI1_DEST_SIGNAL_HIGH      0x00008000
+#define QE_IC_GRP_Y_PRI0_DEST_SIGNAL_HIGH      0x00010000
+#define QE_IC_GRP_Y_PRI1_DEST_SIGNAL_HIGH      0x00020000
+#define QE_IC_GRP_Z_PRI0_DEST_SIGNAL_HIGH      0x00040000
+#define QE_IC_GRP_Z_PRI1_DEST_SIGNAL_HIGH      0x00080000
+#define QE_IC_GRP_RISCA_PRI0_DEST_SIGNAL_HIGH  0x00100000
+#define QE_IC_GRP_RISCA_PRI1_DEST_SIGNAL_HIGH  0x00200000
+#define QE_IC_GRP_RISCB_PRI0_DEST_SIGNAL_HIGH  0x00400000
+#define QE_IC_GRP_RISCB_PRI1_DEST_SIGNAL_HIGH  0x00800000
+#define QE_IC_GRP_W_DEST_SIGNAL_SHIFT          (12)
+
+/* QE interrupt sources groups */
+enum qe_ic_grp_id {
+       QE_IC_GRP_W = 0,        /* QE interrupt controller group W */
+       QE_IC_GRP_X,            /* QE interrupt controller group X */
+       QE_IC_GRP_Y,            /* QE interrupt controller group Y */
+       QE_IC_GRP_Z,            /* QE interrupt controller group Z */
+       QE_IC_GRP_RISCA,        /* QE interrupt controller RISC group A */
+       QE_IC_GRP_RISCB         /* QE interrupt controller RISC group B */
+};
+
+void qe_ic_init(struct device_node *node, unsigned int flags);
+void qe_ic_set_highest_priority(unsigned int virq, int high);
+int qe_ic_set_priority(unsigned int virq, unsigned int priority);
+int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high);
+
+#endif /* _ASM_POWERPC_QE_IC_H */
index 4b41deaa8d8d977e11c2af1376c318fd960f5566..43627596003b8ec7017230fa292aac27c4a52995 100644 (file)
@@ -91,10 +91,6 @@ DEBUGGER_BOILERPLATE(debugger_iabr_match)
 DEBUGGER_BOILERPLATE(debugger_dabr_match)
 DEBUGGER_BOILERPLATE(debugger_fault_handler)
 
-#ifdef CONFIG_XMON
-extern void xmon_init(int enable);
-#endif
-
 #else
 static inline int debugger(struct pt_regs *regs) { return 0; }
 static inline int debugger_ipi(struct pt_regs *regs) { return 0; }
index 5785ac4737b5ee7575837b2d8e8d9c05b752f8cd..b051d4c88c3b46a19b40ba11d2e951010be502d6 100644 (file)
@@ -39,6 +39,10 @@ extern void generic_calibrate_decr(void);
 extern void wakeup_decrementer(void);
 extern void snapshot_timebase(void);
 
+#ifdef CONFIG_RTC_CLASS
+extern int __init rtc_class_hookup(void);
+#endif
+
 /* Some sane defaults: 125 MHz timebase, 1GHz processor */
 extern unsigned long ppc_proc_freq;
 #define DEFAULT_PROC_FREQ      (DEFAULT_TB_FREQ * 8)
@@ -234,4 +238,4 @@ extern void snapshot_timebases(void);
 #endif
 
 #endif /* __KERNEL__ */
-#endif /* __PPC64_TIME_H */
+#endif /* __POWERPC_TIME_H */
index bbc3844b086fcadd9f529c69f5b12b6556530667..8f7ee16781a4d6497c7fb0b8b79993768f67efc2 100644 (file)
@@ -43,6 +43,7 @@ extern int pcibus_to_node(struct pci_bus *bus);
 #define SD_NODE_INIT (struct sched_domain) {           \
        .span                   = CPU_MASK_NONE,        \
        .parent                 = NULL,                 \
+       .child                  = NULL,                 \
        .groups                 = NULL,                 \
        .min_interval           = 8,                    \
        .max_interval           = 32,                   \
diff --git a/include/asm-powerpc/ucc.h b/include/asm-powerpc/ucc.h
new file mode 100644 (file)
index 0000000..afe3076
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
+ *
+ * Authors:    Shlomi Gridish <gridish@freescale.com>
+ *             Li Yang <leoli@freescale.com>
+ *
+ * Description:
+ * Internal header file for UCC unit routines.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#ifndef __UCC_H__
+#define __UCC_H__
+
+#include <asm/immap_qe.h>
+#include <asm/qe.h>
+
+#define STATISTICS
+
+#define UCC_MAX_NUM    8
+
+/* Slow or fast type for UCCs.
+*/
+enum ucc_speed_type {
+       UCC_SPEED_TYPE_FAST, UCC_SPEED_TYPE_SLOW
+};
+
+/* Initial UCCs Parameter RAM address relative to: MEM_MAP_BASE (IMMR).
+*/
+enum ucc_pram_initial_offset {
+       UCC_PRAM_OFFSET_UCC1 = 0x8400,
+       UCC_PRAM_OFFSET_UCC2 = 0x8500,
+       UCC_PRAM_OFFSET_UCC3 = 0x8600,
+       UCC_PRAM_OFFSET_UCC4 = 0x9000,
+       UCC_PRAM_OFFSET_UCC5 = 0x8000,
+       UCC_PRAM_OFFSET_UCC6 = 0x8100,
+       UCC_PRAM_OFFSET_UCC7 = 0x8200,
+       UCC_PRAM_OFFSET_UCC8 = 0x8300
+};
+
+/* ucc_set_type
+ * Sets UCC to slow or fast mode.
+ *
+ * ucc_num - (In) number of UCC (0-7).
+ * regs    - (In) pointer to registers base for the UCC.
+ * speed   - (In) slow or fast mode for UCC.
+ */
+int ucc_set_type(int ucc_num, struct ucc_common *regs,
+                enum ucc_speed_type speed);
+
+/* ucc_init_guemr
+ * Init the Guemr register.
+ *
+ * regs - (In) pointer to registers base for the UCC.
+ */
+int ucc_init_guemr(struct ucc_common *regs);
+
+int ucc_set_qe_mux_mii_mng(int ucc_num);
+
+int ucc_set_qe_mux_rxtx(int ucc_num, enum qe_clock clock, enum comm_dir mode);
+
+int ucc_mux_set_grant_tsa_bkpt(int ucc_num, int set, u32 mask);
+
+/* QE MUX clock routing for UCC
+*/
+static inline int ucc_set_qe_mux_grant(int ucc_num, int set)
+{
+       return ucc_mux_set_grant_tsa_bkpt(ucc_num, set, QE_CMXUCR_GRANT);
+}
+
+static inline int ucc_set_qe_mux_tsa(int ucc_num, int set)
+{
+       return ucc_mux_set_grant_tsa_bkpt(ucc_num, set, QE_CMXUCR_TSA);
+}
+
+static inline int ucc_set_qe_mux_bkpt(int ucc_num, int set)
+{
+       return ucc_mux_set_grant_tsa_bkpt(ucc_num, set, QE_CMXUCR_BKPT);
+}
+
+#endif                         /* __UCC_H__ */
diff --git a/include/asm-powerpc/ucc_fast.h b/include/asm-powerpc/ucc_fast.h
new file mode 100644 (file)
index 0000000..39d1c90
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * include/asm-powerpc/ucc_fast.h
+ *
+ * Internal header file for UCC FAST unit routines.
+ *
+ * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
+ *
+ * Authors:    Shlomi Gridish <gridish@freescale.com>
+ *             Li Yang <leoli@freescale.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#ifndef __UCC_FAST_H__
+#define __UCC_FAST_H__
+
+#include <linux/kernel.h>
+
+#include <asm/immap_qe.h>
+#include <asm/qe.h>
+
+#include "ucc.h"
+
+/* Receive BD's status */
+#define R_E    0x80000000      /* buffer empty */
+#define R_W    0x20000000      /* wrap bit */
+#define R_I    0x10000000      /* interrupt on reception */
+#define R_L    0x08000000      /* last */
+#define R_F    0x04000000      /* first */
+
+/* transmit BD's status */
+#define T_R    0x80000000      /* ready bit */
+#define T_W    0x20000000      /* wrap bit */
+#define T_I    0x10000000      /* interrupt on completion */
+#define T_L    0x08000000      /* last */
+
+/* Rx Data buffer must be 4 bytes aligned in most cases */
+#define UCC_FAST_RX_ALIGN                      4
+#define UCC_FAST_MRBLR_ALIGNMENT               4
+#define UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT      8
+
+/* Sizes */
+#define UCC_FAST_URFS_MIN_VAL                          0x88
+#define UCC_FAST_RECEIVE_VIRTUAL_FIFO_SIZE_FUDGE_FACTOR        8
+
+/* ucc_fast_channel_protocol_mode - UCC FAST mode */
+enum ucc_fast_channel_protocol_mode {
+       UCC_FAST_PROTOCOL_MODE_HDLC = 0x00000000,
+       UCC_FAST_PROTOCOL_MODE_RESERVED01 = 0x00000001,
+       UCC_FAST_PROTOCOL_MODE_RESERVED_QMC = 0x00000002,
+       UCC_FAST_PROTOCOL_MODE_RESERVED02 = 0x00000003,
+       UCC_FAST_PROTOCOL_MODE_RESERVED_UART = 0x00000004,
+       UCC_FAST_PROTOCOL_MODE_RESERVED03 = 0x00000005,
+       UCC_FAST_PROTOCOL_MODE_RESERVED_EX_MAC_1 = 0x00000006,
+       UCC_FAST_PROTOCOL_MODE_RESERVED_EX_MAC_2 = 0x00000007,
+       UCC_FAST_PROTOCOL_MODE_RESERVED_BISYNC = 0x00000008,
+       UCC_FAST_PROTOCOL_MODE_RESERVED04 = 0x00000009,
+       UCC_FAST_PROTOCOL_MODE_ATM = 0x0000000A,
+       UCC_FAST_PROTOCOL_MODE_RESERVED05 = 0x0000000B,
+       UCC_FAST_PROTOCOL_MODE_ETHERNET = 0x0000000C,
+       UCC_FAST_PROTOCOL_MODE_RESERVED06 = 0x0000000D,
+       UCC_FAST_PROTOCOL_MODE_POS = 0x0000000E,
+       UCC_FAST_PROTOCOL_MODE_RESERVED07 = 0x0000000F
+};
+
+/* ucc_fast_transparent_txrx - UCC Fast Transparent TX & RX */
+enum ucc_fast_transparent_txrx {
+       UCC_FAST_GUMR_TRANSPARENT_TTX_TRX_NORMAL = 0x00000000,
+       UCC_FAST_GUMR_TRANSPARENT_TTX_TRX_TRANSPARENT = 0x18000000
+};
+
+/* UCC fast diagnostic mode */
+enum ucc_fast_diag_mode {
+       UCC_FAST_DIAGNOSTIC_NORMAL = 0x0,
+       UCC_FAST_DIAGNOSTIC_LOCAL_LOOP_BACK = 0x40000000,
+       UCC_FAST_DIAGNOSTIC_AUTO_ECHO = 0x80000000,
+       UCC_FAST_DIAGNOSTIC_LOOP_BACK_AND_ECHO = 0xC0000000
+};
+
+/* UCC fast Sync length (transparent mode only) */
+enum ucc_fast_sync_len {
+       UCC_FAST_SYNC_LEN_NOT_USED = 0x0,
+       UCC_FAST_SYNC_LEN_AUTOMATIC = 0x00004000,
+       UCC_FAST_SYNC_LEN_8_BIT = 0x00008000,
+       UCC_FAST_SYNC_LEN_16_BIT = 0x0000C000
+};
+
+/* UCC fast RTS mode */
+enum ucc_fast_ready_to_send {
+       UCC_FAST_SEND_IDLES_BETWEEN_FRAMES = 0x00000000,
+       UCC_FAST_SEND_FLAGS_BETWEEN_FRAMES = 0x00002000
+};
+
+/* UCC fast receiver decoding mode */
+enum ucc_fast_rx_decoding_method {
+       UCC_FAST_RX_ENCODING_NRZ = 0x00000000,
+       UCC_FAST_RX_ENCODING_NRZI = 0x00000800,
+       UCC_FAST_RX_ENCODING_RESERVED0 = 0x00001000,
+       UCC_FAST_RX_ENCODING_RESERVED1 = 0x00001800
+};
+
+/* UCC fast transmitter encoding mode */
+enum ucc_fast_tx_encoding_method {
+       UCC_FAST_TX_ENCODING_NRZ = 0x00000000,
+       UCC_FAST_TX_ENCODING_NRZI = 0x00000100,
+       UCC_FAST_TX_ENCODING_RESERVED0 = 0x00000200,
+       UCC_FAST_TX_ENCODING_RESERVED1 = 0x00000300
+};
+
+/* UCC fast CRC length */
+enum ucc_fast_transparent_tcrc {
+       UCC_FAST_16_BIT_CRC = 0x00000000,
+       UCC_FAST_CRC_RESERVED0 = 0x00000040,
+       UCC_FAST_32_BIT_CRC = 0x00000080,
+       UCC_FAST_CRC_RESERVED1 = 0x000000C0
+};
+
+/* Fast UCC initialization structure */
+struct ucc_fast_info {
+       int ucc_num;
+       enum qe_clock rx_clock;
+       enum qe_clock tx_clock;
+       u32 regs;
+       int irq;
+       u32 uccm_mask;
+       int bd_mem_part;
+       int brkpt_support;
+       int grant_support;
+       int tsa;
+       int cdp;
+       int cds;
+       int ctsp;
+       int ctss;
+       int tci;
+       int txsy;
+       int rtsm;
+       int revd;
+       int rsyn;
+       u16 max_rx_buf_length;
+       u16 urfs;
+       u16 urfet;
+       u16 urfset;
+       u16 utfs;
+       u16 utfet;
+       u16 utftt;
+       u16 ufpt;
+       enum ucc_fast_channel_protocol_mode mode;
+       enum ucc_fast_transparent_txrx ttx_trx;
+       enum ucc_fast_tx_encoding_method tenc;
+       enum ucc_fast_rx_decoding_method renc;
+       enum ucc_fast_transparent_tcrc tcrc;
+       enum ucc_fast_sync_len synl;
+};
+
+struct ucc_fast_private {
+       struct ucc_fast_info *uf_info;
+       struct ucc_fast *uf_regs;       /* a pointer to memory map of UCC regs. */
+       u32 *p_ucce;            /* a pointer to the event register in memory. */
+       u32 *p_uccm;            /* a pointer to the mask register in memory. */
+       int enabled_tx;         /* Whether channel is enabled for Tx (ENT) */
+       int enabled_rx;         /* Whether channel is enabled for Rx (ENR) */
+       int stopped_tx;         /* Whether channel has been stopped for Tx
+                                  (STOP_TX, etc.) */
+       int stopped_rx;         /* Whether channel has been stopped for Rx */
+       u32 ucc_fast_tx_virtual_fifo_base_offset;/* pointer to base of Tx
+                                                   virtual fifo */
+       u32 ucc_fast_rx_virtual_fifo_base_offset;/* pointer to base of Rx
+                                                   virtual fifo */
+#ifdef STATISTICS
+       u32 tx_frames;          /* Transmitted frames counter. */
+       u32 rx_frames;          /* Received frames counter (only frames
+                                  passed to application). */
+       u32 tx_discarded;       /* Discarded tx frames counter (frames that
+                                  were discarded by the driver due to errors).
+                                  */
+       u32 rx_discarded;       /* Discarded rx frames counter (frames that
+                                  were discarded by the driver due to errors).
+                                  */
+#endif                         /* STATISTICS */
+       u16 mrblr;              /* maximum receive buffer length */
+};
+
+/* ucc_fast_init
+ * Initializes Fast UCC according to user provided parameters.
+ *
+ * uf_info  - (In) pointer to the fast UCC info structure.
+ * uccf_ret - (Out) pointer to the fast UCC structure.
+ */
+int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** uccf_ret);
+
+/* ucc_fast_free
+ * Frees all resources for fast UCC.
+ *
+ * uccf - (In) pointer to the fast UCC structure.
+ */
+void ucc_fast_free(struct ucc_fast_private * uccf);
+
+/* ucc_fast_enable
+ * Enables a fast UCC port.
+ * This routine enables Tx and/or Rx through the General UCC Mode Register.
+ *
+ * uccf - (In) pointer to the fast UCC structure.
+ * mode - (In) TX, RX, or both.
+ */
+void ucc_fast_enable(struct ucc_fast_private * uccf, enum comm_dir mode);
+
+/* ucc_fast_disable
+ * Disables a fast UCC port.
+ * This routine disables Tx and/or Rx through the General UCC Mode Register.
+ *
+ * uccf - (In) pointer to the fast UCC structure.
+ * mode - (In) TX, RX, or both.
+ */
+void ucc_fast_disable(struct ucc_fast_private * uccf, enum comm_dir mode);
+
+/* ucc_fast_irq
+ * Handles interrupts on fast UCC.
+ * Called from the general interrupt routine to handle interrupts on fast UCC.
+ *
+ * uccf - (In) pointer to the fast UCC structure.
+ */
+void ucc_fast_irq(struct ucc_fast_private * uccf);
+
+/* ucc_fast_transmit_on_demand
+ * Immediately forces a poll of the transmitter for data to be sent.
+ * Typically, the hardware performs a periodic poll for data that the
+ * transmit routine has set up to be transmitted. In cases where
+ * this polling cycle is not soon enough, this optional routine can
+ * be invoked to force a poll right away, instead. Proper use for
+ * each transmission for which this functionality is desired is to
+ * call the transmit routine and then this routine right after.
+ *
+ * uccf - (In) pointer to the fast UCC structure.
+ */
+void ucc_fast_transmit_on_demand(struct ucc_fast_private * uccf);
+
+u32 ucc_fast_get_qe_cr_subblock(int uccf_num);
+
+void ucc_fast_dump_regs(struct ucc_fast_private * uccf);
+
+#endif                         /* __UCC_FAST_H__ */
diff --git a/include/asm-powerpc/ucc_slow.h b/include/asm-powerpc/ucc_slow.h
new file mode 100644 (file)
index 0000000..ca93bc9
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
+ *
+ * Authors:    Shlomi Gridish <gridish@freescale.com>
+ *             Li Yang <leoli@freescale.com>
+ *
+ * Description:
+ * Internal header file for UCC SLOW unit routines.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#ifndef __UCC_SLOW_H__
+#define __UCC_SLOW_H__
+
+#include <linux/kernel.h>
+
+#include <asm/immap_qe.h>
+#include <asm/qe.h>
+
+#include "ucc.h"
+
+/* transmit BD's status */
+#define T_R    0x80000000      /* ready bit */
+#define T_PAD  0x40000000      /* add pads to short frames */
+#define T_W    0x20000000      /* wrap bit */
+#define T_I    0x10000000      /* interrupt on completion */
+#define T_L    0x08000000      /* last */
+
+#define T_A    0x04000000      /* Address - the data transmitted as address
+                                  chars */
+#define T_TC   0x04000000      /* transmit CRC */
+#define T_CM   0x02000000      /* continuous mode */
+#define T_DEF  0x02000000      /* collision on previous attempt to transmit */
+#define T_P    0x01000000      /* Preamble - send Preamble sequence before
+                                  data */
+#define T_HB   0x01000000      /* heartbeat */
+#define T_NS   0x00800000      /* No Stop */
+#define T_LC   0x00800000      /* late collision */
+#define T_RL   0x00400000      /* retransmission limit */
+#define T_UN   0x00020000      /* underrun */
+#define T_CT   0x00010000      /* CTS lost */
+#define T_CSL  0x00010000      /* carrier sense lost */
+#define T_RC   0x003c0000      /* retry count */
+
+/* Receive BD's status */
+#define R_E    0x80000000      /* buffer empty */
+#define R_W    0x20000000      /* wrap bit */
+#define R_I    0x10000000      /* interrupt on reception */
+#define R_L    0x08000000      /* last */
+#define R_C    0x08000000      /* the last byte in this buffer is a cntl
+                                  char */
+#define R_F    0x04000000      /* first */
+#define R_A    0x04000000      /* the first byte in this buffer is address
+                                  byte */
+#define R_CM   0x02000000      /* continuous mode */
+#define R_ID   0x01000000      /* buffer close on reception of idles */
+#define R_M    0x01000000      /* Frame received because of promiscuous
+                                  mode */
+#define R_AM   0x00800000      /* Address match */
+#define R_DE   0x00800000      /* Address match */
+#define R_LG   0x00200000      /* Break received */
+#define R_BR   0x00200000      /* Frame length violation */
+#define R_NO   0x00100000      /* Rx Non Octet Aligned Packet */
+#define R_FR   0x00100000      /* Framing Error (no stop bit) character
+                                  received */
+#define R_PR   0x00080000      /* Parity Error character received */
+#define R_AB   0x00080000      /* Frame Aborted */
+#define R_SH   0x00080000      /* frame is too short */
+#define R_CR   0x00040000      /* CRC Error */
+#define R_OV   0x00020000      /* Overrun */
+#define R_CD   0x00010000      /* CD lost */
+#define R_CL   0x00010000      /* this frame is closed because of a
+                                  collision */
+
+/* Rx Data buffer must be 4 bytes aligned in most cases.*/
+#define UCC_SLOW_RX_ALIGN              4
+#define UCC_SLOW_MRBLR_ALIGNMENT       4
+#define UCC_SLOW_PRAM_SIZE             0x100
+#define ALIGNMENT_OF_UCC_SLOW_PRAM     64
+
+/* UCC Slow Channel Protocol Mode */
+enum ucc_slow_channel_protocol_mode {
+       UCC_SLOW_CHANNEL_PROTOCOL_MODE_QMC = 0x00000002,
+       UCC_SLOW_CHANNEL_PROTOCOL_MODE_UART = 0x00000004,
+       UCC_SLOW_CHANNEL_PROTOCOL_MODE_BISYNC = 0x00000008,
+};
+
+/* UCC Slow Transparent Transmit CRC (TCRC) */
+enum ucc_slow_transparent_tcrc {
+       /* 16-bit CCITT CRC (HDLC).  (X16 + X12 + X5 + 1) */
+       UCC_SLOW_TRANSPARENT_TCRC_CCITT_CRC16 = 0x00000000,
+       /* CRC16 (BISYNC).  (X16 + X15 + X2 + 1) */
+       UCC_SLOW_TRANSPARENT_TCRC_CRC16 = 0x00004000,
+       /* 32-bit CCITT CRC (Ethernet and HDLC) */
+       UCC_SLOW_TRANSPARENT_TCRC_CCITT_CRC32 = 0x00008000,
+};
+
+/* UCC Slow oversampling rate for transmitter (TDCR) */
+enum ucc_slow_tx_oversampling_rate {
+       /* 1x clock mode */
+       UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_1 = 0x00000000,
+       /* 8x clock mode */
+       UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_8 = 0x00010000,
+       /* 16x clock mode */
+       UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_16 = 0x00020000,
+       /* 32x clock mode */
+       UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_32 = 0x00030000,
+};
+
+/* UCC Slow Oversampling rate for receiver (RDCR)
+*/
+enum ucc_slow_rx_oversampling_rate {
+       /* 1x clock mode */
+       UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_1 = 0x00000000,
+       /* 8x clock mode */
+       UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_8 = 0x00004000,
+       /* 16x clock mode */
+       UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_16 = 0x00008000,
+       /* 32x clock mode */
+       UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_32 = 0x0000c000,
+};
+
+/* UCC Slow Transmitter encoding method (TENC)
+*/
+enum ucc_slow_tx_encoding_method {
+       UCC_SLOW_TRANSMITTER_ENCODING_METHOD_TENC_NRZ = 0x00000000,
+       UCC_SLOW_TRANSMITTER_ENCODING_METHOD_TENC_NRZI = 0x00000100
+};
+
+/* UCC Slow Receiver decoding method (RENC)
+*/
+enum ucc_slow_rx_decoding_method {
+       UCC_SLOW_RECEIVER_DECODING_METHOD_RENC_NRZ = 0x00000000,
+       UCC_SLOW_RECEIVER_DECODING_METHOD_RENC_NRZI = 0x00000800
+};
+
+/* UCC Slow Diagnostic mode (DIAG)
+*/
+enum ucc_slow_diag_mode {
+       UCC_SLOW_DIAG_MODE_NORMAL = 0x00000000,
+       UCC_SLOW_DIAG_MODE_LOOPBACK = 0x00000040,
+       UCC_SLOW_DIAG_MODE_ECHO = 0x00000080,
+       UCC_SLOW_DIAG_MODE_LOOPBACK_ECHO = 0x000000c0
+};
+
+struct ucc_slow_info {
+       int ucc_num;
+       enum qe_clock rx_clock;
+       enum qe_clock tx_clock;
+       struct ucc_slow *us_regs;
+       int irq;
+       u16 uccm_mask;
+       int data_mem_part;
+       int init_tx;
+       int init_rx;
+       u32 tx_bd_ring_len;
+       u32 rx_bd_ring_len;
+       int rx_interrupts;
+       int brkpt_support;
+       int grant_support;
+       int tsa;
+       int cdp;
+       int cds;
+       int ctsp;
+       int ctss;
+       int rinv;
+       int tinv;
+       int rtsm;
+       int rfw;
+       int tci;
+       int tend;
+       int tfl;
+       int txsy;
+       u16 max_rx_buf_length;
+       enum ucc_slow_transparent_tcrc tcrc;
+       enum ucc_slow_channel_protocol_mode mode;
+       enum ucc_slow_diag_mode diag;
+       enum ucc_slow_tx_oversampling_rate tdcr;
+       enum ucc_slow_rx_oversampling_rate rdcr;
+       enum ucc_slow_tx_encoding_method tenc;
+       enum ucc_slow_rx_decoding_method renc;
+};
+
+struct ucc_slow_private {
+       struct ucc_slow_info *us_info;
+       struct ucc_slow *us_regs;       /* a pointer to memory map of UCC regs */
+       struct ucc_slow_pram *us_pram;  /* a pointer to the parameter RAM */
+       u32 us_pram_offset;
+       int enabled_tx;         /* Whether channel is enabled for Tx (ENT) */
+       int enabled_rx;         /* Whether channel is enabled for Rx (ENR) */
+       int stopped_tx;         /* Whether channel has been stopped for Tx
+                                  (STOP_TX, etc.) */
+       int stopped_rx;         /* Whether channel has been stopped for Rx */
+       struct list_head confQ; /* frames passed to chip waiting for tx */
+       u32 first_tx_bd_mask;   /* mask is used in Tx routine to save status
+                                  and length for first BD in a frame */
+       u32 tx_base_offset;     /* first BD in Tx BD table offset (In MURAM) */
+       u32 rx_base_offset;     /* first BD in Rx BD table offset (In MURAM) */
+       u8 *confBd;             /* next BD for confirm after Tx */
+       u8 *tx_bd;              /* next BD for new Tx request */
+       u8 *rx_bd;              /* next BD to collect after Rx */
+       void *p_rx_frame;       /* accumulating receive frame */
+       u16 *p_ucce;            /* a pointer to the event register in memory.
+                                */
+       u16 *p_uccm;            /* a pointer to the mask register in memory */
+       u16 saved_uccm;         /* a saved mask for the RX Interrupt bits */
+#ifdef STATISTICS
+       u32 tx_frames;          /* Transmitted frames counters */
+       u32 rx_frames;          /* Received frames counters (only frames
+                                  passed to application) */
+       u32 rx_discarded;       /* Discarded frames counters (frames that
+                                  were discarded by the driver due to
+                                  errors) */
+#endif                         /* STATISTICS */
+};
+
+/* ucc_slow_init
+ * Initializes Slow UCC according to provided parameters.
+ *
+ * us_info  - (In) pointer to the slow UCC info structure.
+ * uccs_ret - (Out) pointer to the slow UCC structure.
+ */
+int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** uccs_ret);
+
+/* ucc_slow_free
+ * Frees all resources for slow UCC.
+ *
+ * uccs - (In) pointer to the slow UCC structure.
+ */
+void ucc_slow_free(struct ucc_slow_private * uccs);
+
+/* ucc_slow_enable
+ * Enables a fast UCC port.
+ * This routine enables Tx and/or Rx through the General UCC Mode Register.
+ *
+ * uccs - (In) pointer to the slow UCC structure.
+ * mode - (In) TX, RX, or both.
+ */
+void ucc_slow_enable(struct ucc_slow_private * uccs, enum comm_dir mode);
+
+/* ucc_slow_disable
+ * Disables a fast UCC port.
+ * This routine disables Tx and/or Rx through the General UCC Mode Register.
+ *
+ * uccs - (In) pointer to the slow UCC structure.
+ * mode - (In) TX, RX, or both.
+ */
+void ucc_slow_disable(struct ucc_slow_private * uccs, enum comm_dir mode);
+
+/* ucc_slow_poll_transmitter_now
+ * Immediately forces a poll of the transmitter for data to be sent.
+ * Typically, the hardware performs a periodic poll for data that the
+ * transmit routine has set up to be transmitted. In cases where
+ * this polling cycle is not soon enough, this optional routine can
+ * be invoked to force a poll right away, instead. Proper use for
+ * each transmission for which this functionality is desired is to
+ * call the transmit routine and then this routine right after.
+ *
+ * uccs - (In) pointer to the slow UCC structure.
+ */
+void ucc_slow_poll_transmitter_now(struct ucc_slow_private * uccs);
+
+/* ucc_slow_graceful_stop_tx
+ * Smoothly stops transmission on a specified slow UCC.
+ *
+ * uccs - (In) pointer to the slow UCC structure.
+ */
+void ucc_slow_graceful_stop_tx(struct ucc_slow_private * uccs);
+
+/* ucc_slow_stop_tx
+ * Stops transmission on a specified slow UCC.
+ *
+ * uccs - (In) pointer to the slow UCC structure.
+ */
+void ucc_slow_stop_tx(struct ucc_slow_private * uccs);
+
+/* ucc_slow_restart_x
+ * Restarts transmitting on a specified slow UCC.
+ *
+ * uccs - (In) pointer to the slow UCC structure.
+ */
+void ucc_slow_restart_x(struct ucc_slow_private * uccs);
+
+u32 ucc_slow_get_qe_cr_subblock(int uccs_num);
+
+#endif                         /* __UCC_SLOW_H__ */
index eb66eae6616fb3026dbf38f966afff686664601c..464a48cce7f51c561f799eb67f95a7e50473c3a2 100644 (file)
@@ -478,13 +478,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
 #define __ARCH_WANT_SYS_NEWFSTATAT
 #endif
 
-/*
- * System call prototypes.
- */
-#ifdef __KERNEL_SYSCALLS__
-extern int execve(const char *file, char **argv, char **envp);
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  *
index 43f7129984c723312c3ca394ccf32fe53d52a4e8..f1d337ed68d5bfdaf16ee9eaf6823ffa2ead81d7 100644 (file)
@@ -1,12 +1,22 @@
-#ifndef __PPC_XMON_H
-#define __PPC_XMON_H
-#ifdef __KERNEL__
+#ifndef __ASM_POWERPC_XMON_H
+#define __ASM_POWERPC_XMON_H
 
-struct pt_regs;
+/*
+ * Copyrignt (C) 2006 IBM Corp
+ *
+ * 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.
+ */
 
-extern int xmon(struct pt_regs *excp);
-extern void xmon_printf(const char *fmt, ...);
-extern void xmon_init(int);
+#ifdef __KERNEL__
 
+#ifdef CONFIG_XMON
+extern void xmon_setup(void);
+#else
+static inline void xmon_setup(void) { };
 #endif
-#endif
+
+#endif /* __KERNEL __ */
+#endif /* __ASM_POWERPC_XMON_H */
index f6a7ff04ffe5030a46092538ce31c99ac9478c3e..220cc2debe089ee92c5daa70caa3590e5494b5ea 100644 (file)
@@ -42,6 +42,8 @@
 #define CPM_CR_IDMA4_SBLOCK    (0x17)
 #define CPM_CR_MCC1_SBLOCK     (0x1c)
 
+#define CPM_CR_FCC_SBLOCK(x)   (x + 0x10)
+
 #define CPM_CR_SCC1_PAGE       (0x00)
 #define CPM_CR_SCC2_PAGE       (0x01)
 #define CPM_CR_SCC3_PAGE       (0x02)
@@ -62,6 +64,8 @@
 #define CPM_CR_MCC1_PAGE       (0x07)
 #define CPM_CR_MCC2_PAGE       (0x08)
 
+#define CPM_CR_FCC_PAGE(x)     (x + 0x04)
+
 /* Some opcodes (there are more...later)
 */
 #define CPM_CR_INIT_TRX                ((ushort)0x0000)
@@ -173,6 +177,10 @@ typedef struct cpm_buf_desc {
 #define PROFF_I2C_BASE         ((uint)0x8afc)
 #define PROFF_IDMA4_BASE       ((uint)0x8afe)
 
+#define PROFF_SCC_SIZE         ((uint)0x100)
+#define PROFF_FCC_SIZE         ((uint)0x100)
+#define PROFF_SMC_SIZE         ((uint)64)
+
 /* The SMCs are relocated to any of the first eight DPRAM pages.
  * We will fix these at the first locations of DPRAM, until we
  * get some microcode patches :-).
@@ -1186,7 +1194,60 @@ typedef struct im_idma {
 #define FCC_MEM_OFFSET(x) (CPM_FCC_SPECIAL_BASE + (x*128))
 #define FCC1_MEM_OFFSET FCC_MEM_OFFSET(0)
 #define FCC2_MEM_OFFSET FCC_MEM_OFFSET(1)
-#define FCC2_MEM_OFFSET FCC_MEM_OFFSET(2)
+#define FCC3_MEM_OFFSET FCC_MEM_OFFSET(2)
+
+/* Clocks and GRG's */
+
+enum cpm_clk_dir {
+       CPM_CLK_RX,
+       CPM_CLK_TX,
+       CPM_CLK_RTX
+};
+
+enum cpm_clk_target {
+       CPM_CLK_SCC1,
+       CPM_CLK_SCC2,
+       CPM_CLK_SCC3,
+       CPM_CLK_SCC4,
+       CPM_CLK_FCC1,
+       CPM_CLK_FCC2,
+       CPM_CLK_FCC3
+};
+
+enum cpm_clk {
+       CPM_CLK_NONE = 0,
+       CPM_BRG1,       /* Baud Rate Generator  1 */
+       CPM_BRG2,       /* Baud Rate Generator  2 */
+       CPM_BRG3,       /* Baud Rate Generator  3 */
+       CPM_BRG4,       /* Baud Rate Generator  4 */
+       CPM_BRG5,       /* Baud Rate Generator  5 */
+       CPM_BRG6,       /* Baud Rate Generator  6 */
+       CPM_BRG7,       /* Baud Rate Generator  7 */
+       CPM_BRG8,       /* Baud Rate Generator  8 */
+       CPM_CLK1,       /* Clock  1 */
+       CPM_CLK2,       /* Clock  2 */
+       CPM_CLK3,       /* Clock  3 */
+       CPM_CLK4,       /* Clock  4 */
+       CPM_CLK5,       /* Clock  5 */
+       CPM_CLK6,       /* Clock  6 */
+       CPM_CLK7,       /* Clock  7 */
+       CPM_CLK8,       /* Clock  8 */
+       CPM_CLK9,       /* Clock  9 */
+       CPM_CLK10,      /* Clock 10 */
+       CPM_CLK11,      /* Clock 11 */
+       CPM_CLK12,      /* Clock 12 */
+       CPM_CLK13,      /* Clock 13 */
+       CPM_CLK14,      /* Clock 14 */
+       CPM_CLK15,      /* Clock 15 */
+       CPM_CLK16,      /* Clock 16 */
+       CPM_CLK17,      /* Clock 17 */
+       CPM_CLK18,      /* Clock 18 */
+       CPM_CLK19,      /* Clock 19 */
+       CPM_CLK20,      /* Clock 20 */
+       CPM_CLK_DUMMY
+};
+
+extern int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode);
 
 #endif /* __CPM2__ */
 #endif /* __KERNEL__ */
diff --git a/include/asm-ppc/fs_pd.h b/include/asm-ppc/fs_pd.h
new file mode 100644 (file)
index 0000000..8691327
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Platform information definitions.
+ *
+ * 2006 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef FS_PD_H
+#define FS_PD_H
+
+static inline int uart_baudrate(void)
+{
+       int baud;
+       bd_t *bd = (bd_t *) __res;
+
+       if (bd->bi_baudrate)
+               baud = bd->bi_baudrate;
+       else
+               baud = -1;
+       return baud;
+}
+
+static inline int uart_clock(void)
+{
+       return (((bd_t *) __res)->bi_intfreq);
+}
+
+#define cpm2_map(member)       (&cpm2_immr->member)
+#define cpm2_map_size(member, size)    (&cpm2_immr->member)
+#define cpm2_unmap(addr)        do {} while(0)
+
+#endif
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 e6ca1f67cedc0e526ad36d9dba1c784d88db7ad2..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.
  *
@@ -62,6 +62,10 @@ extern int rh_attach_region(rh_info_t * info, void *start, int size);
 /* Detach a free region */
 extern void *rh_detach_region(rh_info_t * info, void *start, int size);
 
+/* Allocate the given size from the remote heap (with alignment) */
+extern void *rh_alloc_align(rh_info_t * info, int size, int alignment,
+               const char *owner);
+
 /* Allocate the given size from the remote heap */
 extern void *rh_alloc(rh_info_t * info, int size, const char *owner);
 
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 8d2bf65b0b6487a4c64df4444f3740d16c0428cb..7b768c5c68a8226b43cffbfb44ce7f9ed9aa4615 100644 (file)
@@ -472,6 +472,7 @@ struct user_regs_struct
 
 #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
 #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN)
+#define regs_return_value(regs)((regs)->gprs[2])
 #define profile_pc(regs) instruction_pointer(regs)
 extern void show_regs(struct pt_regs * regs);
 #endif
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 0361ac5dcde38333183b8e1e89676b61d28c37bf..0cccfd83c45758e7b9d367442efcb6094567ba7a 100644 (file)
@@ -523,57 +523,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4,  \
 #   define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
 # endif
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <asm/ptrace.h>
-#include <asm/stat.h>
-#include <linux/syscalls.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static inline _syscall0(pid_t,setsid)
-static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
-static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
-static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
-static inline _syscall1(int,dup,int,fd)
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
-static inline _syscall1(int,close,int,fd)
-static inline _syscall2(long,stat,char *,filename,struct stat *,statbuf)
-
-static inline pid_t waitpid(int pid, int *wait_stat, int flags)
-{
-       return sys_wait4(pid, wait_stat, flags, NULL);
-}
-struct mmap_arg_struct;
-asmlinkage long sys_mmap2(struct mmap_arg_struct __user *arg);
-
-asmlinkage long sys_execve(struct pt_regs regs);
-asmlinkage long sys_clone(struct pt_regs regs);
-asmlinkage long sys_fork(struct pt_regs regs);
-asmlinkage long sys_vfork(struct pt_regs regs);
-asmlinkage long sys_pipe(unsigned long __user *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-                               const struct sigaction __user *act,
-                               struct sigaction __user *oact,
-                               size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  *
diff --git a/include/asm-sh/.gitignore b/include/asm-sh/.gitignore
new file mode 100644 (file)
index 0000000..9218ef8
--- /dev/null
@@ -0,0 +1,3 @@
+cpu
+mach
+machtypes.h
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 b4000c8bf31b8b76161b93c227a9bfa24c8ad0a3..beeea40f549ec391248d0a0673851f478c3dad17 100644 (file)
@@ -18,7 +18,7 @@ static void __init check_bugs(void)
 {
        extern char *get_cpu_subtype(void);
        extern unsigned long loops_per_jiffy;
-       char *p= &system_utsname.machine[2]; /* "sh" */
+       char *p= &init_utsname()->machine[2]; /* "sh" */
 
        cpu_data->loops_per_jiffy = loops_per_jiffy;
 
diff --git a/include/asm-sh/cpu-sh3/rtc.h b/include/asm-sh/cpu-sh3/rtc.h
deleted file mode 100644 (file)
index 2d92667..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef __ASM_CPU_SH3_RTC_H
-#define __ASM_CPU_SH3_RTC_H
-
-/* SH-3 RTC */
-#define R64CNT         0xfffffec0
-#define RSECCNT        0xfffffec2
-#define RMINCNT        0xfffffec4
-#define RHRCNT         0xfffffec6
-#define RWKCNT         0xfffffec8
-#define RDAYCNT        0xfffffeca
-#define RMONCNT        0xfffffecc
-#define RYRCNT         0xfffffece
-#define RSECAR         0xfffffed0
-#define RMINAR         0xfffffed2
-#define RHRAR          0xfffffed4
-#define RWKAR          0xfffffed6
-#define RDAYAR         0xfffffed8
-#define RMONAR         0xfffffeda
-#define RCR1           0xfffffedc
-#define RCR2           0xfffffede
-
-#define RTC_BIT_INVERTED       0       /* No bug on SH7708, SH7709A */
-
-#endif /* __ASM_CPU_SH3_RTC_H */
-
diff --git a/include/asm-sh/cpu-sh4/rtc.h b/include/asm-sh/cpu-sh4/rtc.h
deleted file mode 100644 (file)
index e091e32..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef __ASM_CPU_SH4_RTC_H
-#define __ASM_CPU_SH4_RTC_H
-
-/* SH-4 RTC */
-#define R64CNT         0xffc80000
-#define RSECCNT        0xffc80004
-#define RMINCNT        0xffc80008
-#define RHRCNT         0xffc8000c
-#define RWKCNT         0xffc80010
-#define RDAYCNT        0xffc80014
-#define RMONCNT        0xffc80018
-#define RYRCNT         0xffc8001c  /* 16bit */
-#define RSECAR         0xffc80020
-#define RMINAR         0xffc80024
-#define RHRAR          0xffc80028
-#define RWKAR          0xffc8002c
-#define RDAYAR         0xffc80030
-#define RMONAR         0xffc80034
-#define RCR1           0xffc80038
-#define RCR2           0xffc8003c
-
-#define RTC_BIT_INVERTED       0x40    /* bug on SH7750, SH7750S */
-
-#endif /* __ASM_CPU_SH4_RTC_H */
-
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 3a07ab40ac4d0a66eab64eb094f538e08fef68bb..fc050fd7645e0e11c29fcf63cf7e1554dca148e7 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef __ASM_SH_ELF_H
 #define __ASM_SH_ELF_H
 
-#include <asm/processor.h>
 #include <asm/auxvec.h>
 #include <asm/ptrace.h>
 #include <asm/user.h>
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.
diff --git a/include/asm-sh/hs7751rvoip/io.h b/include/asm-sh/hs7751rvoip/io.h
deleted file mode 100644 (file)
index 513c851..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * include/asm-sh/hs7751rvoip/hs7751rvoip.h
- *
- * Modified version of io_se.h for the hs7751rvoip-specific functions.
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * IO functions for an Renesas Technology sales HS7751RVOIP
- */
-
-#ifndef _ASM_SH_IO_HS7751RVOIP_H
-#define _ASM_SH_IO_HS7751RVOIP_H
-
-#include <asm/io_generic.h>
-
-extern unsigned char hs7751rvoip_inb(unsigned long port);
-extern unsigned short hs7751rvoip_inw(unsigned long port);
-extern unsigned int hs7751rvoip_inl(unsigned long port);
-
-extern void hs7751rvoip_outb(unsigned char value, unsigned long port);
-extern void hs7751rvoip_outw(unsigned short value, unsigned long port);
-extern void hs7751rvoip_outl(unsigned int value, unsigned long port);
-
-extern unsigned char hs7751rvoip_inb_p(unsigned long port);
-extern void hs7751rvoip_outb_p(unsigned char value, unsigned long port);
-
-extern void hs7751rvoip_insb(unsigned long port, void *addr, unsigned long count);
-extern void hs7751rvoip_insw(unsigned long port, void *addr, unsigned long count);
-extern void hs7751rvoip_insl(unsigned long port, void *addr, unsigned long count);
-extern void hs7751rvoip_outsb(unsigned long port, const void *addr, unsigned long count);
-extern void hs7751rvoip_outsw(unsigned long port, const void *addr, unsigned long count);
-extern void hs7751rvoip_outsl(unsigned long port, const void *addr, unsigned long count);
-
-extern void *hs7751rvoip_ioremap(unsigned long offset, unsigned long size);
-
-extern unsigned long hs7751rvoip_isa_port2addr(unsigned long offset);
-
-#endif /* _ASM_SH_IO_HS7751RVOIP_H */
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
  *
diff --git a/include/asm-sh/rts7751r2d/io.h b/include/asm-sh/rts7751r2d/io.h
deleted file mode 100644 (file)
index 2410940..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * include/asm-sh/io_rts7751r2d.h
- *
- * Modified version of io_se.h for the rts7751r2d-specific functions.
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * IO functions for an Renesas Technology sales RTS7751R2D
- */
-
-#ifndef _ASM_SH_IO_RTS7751R2D_H
-#define _ASM_SH_IO_RTS7751R2D_H
-
-extern unsigned char rts7751r2d_inb(unsigned long port);
-extern unsigned short rts7751r2d_inw(unsigned long port);
-extern unsigned int rts7751r2d_inl(unsigned long port);
-
-extern void rts7751r2d_outb(unsigned char value, unsigned long port);
-extern void rts7751r2d_outw(unsigned short value, unsigned long port);
-extern void rts7751r2d_outl(unsigned int value, unsigned long port);
-
-extern unsigned char rts7751r2d_inb_p(unsigned long port);
-extern void rts7751r2d_outb_p(unsigned char value, unsigned long port);
-
-extern void rts7751r2d_insb(unsigned long port, void *addr, unsigned long count);
-extern void rts7751r2d_insw(unsigned long port, void *addr, unsigned long count);
-extern void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count);
-extern void rts7751r2d_outsb(unsigned long port, const void *addr, unsigned long count);
-extern void rts7751r2d_outsw(unsigned long port, const void *addr, unsigned long count);
-extern void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count);
-
-extern void *rts7751r2d_ioremap(unsigned long offset, unsigned long size);
-
-extern unsigned long rts7751r2d_isa_port2addr(unsigned long offset);
-
-#endif /* _ASM_SH_IO_RTS7751R2D_H */
index b112ae221fd1f4ca0b6ac87cb50909df83037544..796b8fcb81a8984ce5d887e49840d3c0f5fd74d3 100644 (file)
@@ -68,4 +68,7 @@
 #define IRQ_PCISLOT2   10              /* PCI Slot #2 IRQ */
 #define        IRQ_EXTENTION   11              /* EXTn IRQ */
 
+#define __IO_PREFIX rts7751r2d
+#include <asm/io_generic.h>
+
 #endif  /* __ASM_SH_RENESAS_RTS7751R2D */
index 8a6399a8cfe0c4ac71548ed591aa67c55abbb0fa..d3c548443f2a6e7774e7f1f2fd6789e2d129d9c0 100644 (file)
@@ -25,8 +25,6 @@
 #ifndef _SFP_MACHINE_H
 #define _SFP_MACHINE_H
 
-#include <linux/config.h>
-
 #define _FP_W_TYPE_SIZE                32
 #define _FP_W_TYPE             unsigned long
 #define _FP_WS_TYPE            signed long
index 54458fd2498150ce964e159748faac8339c1f235..2586eef07d57214ec977f50b818d61c1c0fff9ed 100644 (file)
@@ -88,7 +88,14 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw)
        __raw_spin_unlock(&rw->lock);
 }
 
-#define __raw_read_trylock(lock) generic__raw_read_trylock(lock)
+static inline int __raw_read_trylock(raw_rwlock_t *lock)
+{
+       atomic_t *count = (atomic_t*)lock;
+       if (atomic_dec_return(count) >= 0)
+               return 1;
+       atomic_inc(count);
+       return 0;
+}
 
 static inline int __raw_write_trylock(raw_rwlock_t *rw)
 {
index 3e0cff04caec8c32adb8c4bcda7a9f209243377d..95bc7db006b0761db05829e730323533e2553970 100644 (file)
@@ -1,13 +1,15 @@
 #ifndef __ASM_SH_STRING_H
 #define __ASM_SH_STRING_H
 
+#ifdef __KERNEL__
+
 /*
  * Copyright (C) 1999 Niibe Yutaka
  * But consider these trivial functions to be public domain.
  */
 
 #define __HAVE_ARCH_STRCPY
-static __inline__ char *strcpy(char *__dest, const char *__src)
+static inline char *strcpy(char *__dest, const char *__src)
 {
        register char *__xdest = __dest;
        unsigned long __dummy;
@@ -26,7 +28,7 @@ static __inline__ char *strcpy(char *__dest, const char *__src)
 }
 
 #define __HAVE_ARCH_STRNCPY
-static __inline__ char *strncpy(char *__dest, const char *__src, size_t __n)
+static inline char *strncpy(char *__dest, const char *__src, size_t __n)
 {
        register char *__xdest = __dest;
        unsigned long __dummy;
@@ -52,7 +54,7 @@ static __inline__ char *strncpy(char *__dest, const char *__src, size_t __n)
 }
 
 #define __HAVE_ARCH_STRCMP
-static __inline__ int strcmp(const char *__cs, const char *__ct)
+static inline int strcmp(const char *__cs, const char *__ct)
 {
        register int __res;
        unsigned long __dummy;
@@ -78,7 +80,7 @@ static __inline__ int strcmp(const char *__cs, const char *__ct)
 }
 
 #define __HAVE_ARCH_STRNCMP
-static __inline__ int strncmp(const char *__cs, const char *__ct, size_t __n)
+static inline int strncmp(const char *__cs, const char *__ct, size_t __n)
 {
        register int __res;
        unsigned long __dummy;
@@ -124,4 +126,9 @@ extern void *memchr(const void *__s, int __c, size_t __n);
 #define __HAVE_ARCH_STRLEN
 extern size_t strlen(const char *);
 
+/* arch/sh/lib/strcasecmp.c */
+extern int strcasecmp(const char *, const char *);
+
+#endif /* __KERNEL__ */
+
 #endif /* __ASM_SH_STRING_H */
index 5d5e9f94def587192e726bb59c5079585580629f..f1a0cbc966be0c8667a5acf7afe54982c043a9bc 100644 (file)
@@ -472,76 +472,6 @@ __syscall_return(type,__sc0); \
 #define __ARCH_WANT_SYS_RT_SIGACTION
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/linkage.h>
-#include <asm/ptrace.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static __inline__ _syscall0(int,pause)
-static __inline__ _syscall0(int,sync)
-static __inline__ _syscall0(pid_t,setsid)
-static __inline__ _syscall3(int,write,int,fd,const char *,buf,off_t,count)
-static __inline__ _syscall3(int,read,int,fd,char *,buf,off_t,count)
-static __inline__ _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
-static __inline__ _syscall1(int,dup,int,fd)
-static __inline__ _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-static __inline__ _syscall3(int,open,const char *,file,int,flag,int,mode)
-static __inline__ _syscall1(int,close,int,fd)
-static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-static __inline__ _syscall1(int,delete_module,const char *,name)
-
-static __inline__ pid_t wait(int * wait_stat)
-{
-       return waitpid(-1,wait_stat,0);
-}
-
-asmlinkage long sys_mmap2(
-                       unsigned long addr, unsigned long len,
-                       unsigned long prot, unsigned long flags,
-                       unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_execve(char *ufilename, char **uargv,
-                       char **uenvp, unsigned long r7,
-                       struct pt_regs regs);
-asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
-                       unsigned long parent_tidptr,
-                       unsigned long child_tidptr,
-                       struct pt_regs regs);
-asmlinkage int sys_fork(unsigned long r4, unsigned long r5,
-                       unsigned long r6, unsigned long r7,
-                       struct pt_regs regs);
-asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
-                       unsigned long r6, unsigned long r7,
-                       struct pt_regs regs);
-asmlinkage int sys_pipe(unsigned long r4, unsigned long r5,
-                       unsigned long r6, unsigned long r7,
-                       struct pt_regs regs);
-asmlinkage ssize_t sys_pread_wrapper(unsigned int fd, char *buf,
-                               size_t count, long dummy, loff_t pos);
-asmlinkage ssize_t sys_pwrite_wrapper(unsigned int fd, const char *buf,
-                               size_t count, long dummy, loff_t pos);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-                               const struct sigaction __user *act,
-                               struct sigaction __user *oact,
-                               size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  *
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 c113566bef3320b348f337a684688323b3e723f6..ee7828b27ad19334f694a440330cfb03ee56298a 100644 (file)
@@ -513,47 +513,6 @@ __syscall_return(type,__sc0);                                                  \
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 
-#ifdef __KERNEL_SYSCALLS__
-
-/* Copy from sh */
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <asm/ptrace.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static inline _syscall0(int,pause)
-static inline _syscall1(int,setup,int,magic)
-static inline _syscall0(int,sync)
-static inline _syscall0(pid_t,setsid)
-static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
-static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
-static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
-static inline _syscall1(int,dup,int,fd)
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
-static inline _syscall1(int,close,int,fd)
-static inline _syscall1(int,_exit,int,exitcode)
-static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-static inline _syscall1(int,delete_module,const char *,name)
-
-static inline pid_t wait(int * wait_stat)
-{
-       return waitpid(-1,wait_stat,0);
-}
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  *
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 2553762465ca78f1d31cdaf10d57f6d8279bf4c0..c7a495afc82ece5359e811c4e05a670a7b99a35e 100644 (file)
@@ -478,53 +478,6 @@ return -1; \
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static __inline__ _syscall0(pid_t,setsid)
-static __inline__ _syscall3(int,write,int,fd,__const__ char *,buf,off_t,count)
-static __inline__ _syscall3(int,read,int,fd,char *,buf,off_t,count)
-static __inline__ _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
-static __inline__ _syscall1(int,dup,int,fd)
-static __inline__ _syscall3(int,execve,__const__ char *,file,char **,argv,char **,envp)
-static __inline__ _syscall3(int,open,__const__ char *,file,int,flag,int,mode)
-static __inline__ _syscall1(int,close,int,fd)
-static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-
-#include <linux/linkage.h>
-
-asmlinkage unsigned long sys_mmap(
-                               unsigned long addr, unsigned long len,
-                               unsigned long prot, unsigned long flags,
-                               unsigned long fd, unsigned long off);
-asmlinkage unsigned long sys_mmap2(
-                               unsigned long addr, unsigned long len,
-                               unsigned long prot, unsigned long flags,
-                               unsigned long fd, unsigned long pgoff);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-                               const struct sigaction __user *act,
-                               struct sigaction __user *oact,
-                               void __user *restorer,
-                               size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  *
diff --git a/include/asm-sparc64/compat_signal.h b/include/asm-sparc64/compat_signal.h
new file mode 100644 (file)
index 0000000..7aefa30
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef _COMPAT_SIGNAL_H
+#define _COMPAT_SIGNAL_H
+
+#include <linux/config.h>
+#include <linux/compat.h>
+#include <asm/signal.h>
+
+#ifdef CONFIG_COMPAT
+struct __new_sigaction32 {
+       unsigned                sa_handler;
+       unsigned int            sa_flags;
+       unsigned                sa_restorer;     /* not used by Linux/SPARC yet */
+       compat_sigset_t         sa_mask;
+};
+
+struct __old_sigaction32 {
+       unsigned                sa_handler;
+       compat_old_sigset_t     sa_mask;
+       unsigned int            sa_flags;
+       unsigned                sa_restorer;     /* not used by Linux/SPARC yet */
+};
+
+typedef struct sigaltstack32 {
+       u32                     ss_sp;
+       int                     ss_flags;
+       compat_size_t           ss_size;
+} stack_t32;
+#endif
+
+#endif /* !(_COMPAT_SIGNAL_H) */
index 9968871103bcf79cf2b802b4c6ea9516cfdf0da8..fa6f467389db2735daf794361b481a08b40ec942 100644 (file)
@@ -8,7 +8,6 @@
 #ifndef __ASSEMBLY__
 #include <linux/personality.h>
 #include <linux/types.h>
-#include <linux/compat.h>
 #endif
 #endif
 
@@ -167,23 +166,6 @@ struct __new_sigaction {
        __new_sigset_t          sa_mask;
 };
 
-#ifdef __KERNEL__
-
-#ifdef CONFIG_COMPAT
-struct __new_sigaction32 {
-       unsigned                sa_handler;
-       unsigned int            sa_flags;
-       unsigned                sa_restorer;     /* not used by Linux/SPARC yet */
-       compat_sigset_t         sa_mask;
-};
-#endif
-
-struct k_sigaction {
-       struct __new_sigaction  sa;
-       void __user             *ka_restorer;
-};
-#endif
-
 struct __old_sigaction {
        __sighandler_t          sa_handler;
        __old_sigset_t          sa_mask;
@@ -191,19 +173,6 @@ struct __old_sigaction {
        void                    (*sa_restorer)(void);     /* not used by Linux/SPARC yet */
 };
 
-#ifdef __KERNEL__
-
-#ifdef CONFIG_COMPAT
-struct __old_sigaction32 {
-       unsigned                sa_handler;
-       compat_old_sigset_t     sa_mask;
-       unsigned int            sa_flags;
-       unsigned                sa_restorer;     /* not used by Linux/SPARC yet */
-};
-#endif
-
-#endif
-
 typedef struct sigaltstack {
        void                    __user *ss_sp;
        int                     ss_flags;
@@ -212,13 +181,10 @@ typedef struct sigaltstack {
 
 #ifdef __KERNEL__
 
-#ifdef CONFIG_COMPAT
-typedef struct sigaltstack32 {
-       u32                     ss_sp;
-       int                     ss_flags;
-       compat_size_t           ss_size;
-} stack_t32;
-#endif
+struct k_sigaction {
+       struct __new_sigaction  sa;
+       void __user             *ka_restorer;
+};
 
 struct signal_deliver_cookie {
        int restart_syscall;
index badc73fdcb97c261a1011db687a45a4ac88b59a5..124cf076717f25d8c3edfc1a54caae609cf6147d 100644 (file)
@@ -445,48 +445,6 @@ if (__res>=0) \
 errno = -__res; \
 return -1; \
 }
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static __inline__ _syscall0(pid_t,setsid)
-static __inline__ _syscall3(int,write,int,fd,__const__ char *,buf,off_t,count)
-static __inline__ _syscall3(int,read,int,fd,char *,buf,off_t,count)
-static __inline__ _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
-static __inline__ _syscall1(int,dup,int,fd)
-static __inline__ _syscall3(int,execve,__const__ char *,file,char **,argv,char **,envp)
-static __inline__ _syscall3(int,open,__const__ char *,file,int,flag,int,mode)
-static __inline__ _syscall1(int,close,int,fd)
-static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-
-#include <linux/linkage.h>
-
-asmlinkage unsigned long sys_mmap(
-                               unsigned long addr, unsigned long len,
-                               unsigned long prot, unsigned long flags,
-                               unsigned long fd, unsigned long off);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-                               const struct sigaction __user *act,
-                               struct sigaction __user *oact,
-                               void __user *restorer,
-                               size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
 
 /* sysconf options, for SunOS compatibility */
 #define   _SC_ARG_MAX             1
index afccfcaa9ea9228d0c744d371815266d7afe0233..732c83f04c3d29d71071b80a1061542db3023d22 100644 (file)
@@ -37,34 +37,6 @@ extern int um_execve(const char *file, char *const argv[], char *const env[]);
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
 #endif
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-
-static inline int execve(const char *filename, char *const argv[],
-                        char *const envp[])
-{
-       mm_segment_t fs;
-       int ret;
-
-       fs = get_fs();
-       set_fs(KERNEL_DS);
-       ret = um_execve(filename, argv, envp);
-       set_fs(fs);
-
-       if (ret >= 0)
-               return ret;
-
-       errno = -(long)ret;
-       return -1;
-}
-
-int sys_execve(char *file, char **argv, char **env);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
-#undef __KERNEL_SYSCALLS__
 #include "asm/arch/unistd.h"
 
 #endif /* _UM_UNISTD_H_*/
index 552b7c873a5702790d913ed85a4270baa4b3455e..737401e7d3ad33a5c398577bfb465354d6e6b7dc 100644 (file)
@@ -387,57 +387,6 @@ type name (atype a, btype b, ctype c, dtype d, etype e, ftype f)         \
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-extern inline _syscall0(pid_t,setsid)
-extern inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
-extern inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
-extern inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
-extern inline _syscall1(int,dup,int,fd)
-extern inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-extern inline _syscall3(int,open,const char *,file,int,flag,int,mode)
-extern inline _syscall1(int,close,int,fd)
-extern inline _syscall1(int,_exit,int,exitcode)
-extern inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-
-extern inline pid_t wait(int * wait_stat)
-{
-       return waitpid (-1, wait_stat, 0);
-}
-
-unsigned long sys_mmap(unsigned long addr, size_t len,
-                       unsigned long prot, unsigned long flags,
-                       unsigned long fd, off_t offset);
-unsigned long sys_mmap2(unsigned long addr, size_t len,
-                       unsigned long prot, unsigned long flags,
-                       unsigned long fd, unsigned long pgoff);
-struct pt_regs;
-int sys_execve (char *name, char **argv, char **envp, struct pt_regs *regs);
-int sys_pipe (int *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-                               const struct sigaction __user *act,
-                               struct sigaction __user *oact,
-                               size_t sigsetsize);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
 /*
  * "Conditional" syscalls
  */
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 ab827dc381d7f3c0afe18b37811d817b7b6e7d73..5ea84dbb1e9ce5f07278cb678f00291fbc64e0a5 100644 (file)
@@ -39,6 +39,8 @@ struct pt_regs {
 #define user_mode(regs) (!!((regs)->cs & 3))
 #define user_mode_vm(regs) user_mode(regs)
 #define instruction_pointer(regs) ((regs)->rip)
+#define regs_return_value(regs) ((regs)->rax)
+
 extern unsigned long profile_pc(struct pt_regs *regs);
 void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
 
index 6e7a2e976b04fc8bc8a98213522fabf5c623af02..5c8f49280dbcc273d718bfd1d9895403910a3ca5 100644 (file)
@@ -31,6 +31,7 @@ extern int __node_distance(int, int);
 #define SD_NODE_INIT (struct sched_domain) {           \
        .span                   = CPU_MASK_NONE,        \
        .parent                 = NULL,                 \
+       .child                  = NULL,                 \
        .groups                 = NULL,                 \
        .min_interval           = 8,                    \
        .max_interval           = 32,                   \
index 6137146516d3905ef58c931f56fc7951a26ad194..777288eb7e75ecc5272599a3995874162ab4c1b2 100644 (file)
@@ -620,10 +620,11 @@ __SYSCALL(__NR_vmsplice, sys_vmsplice)
 #define __NR_move_pages                279
 __SYSCALL(__NR_move_pages, sys_move_pages)
 
-#ifdef __KERNEL__
-
 #define __NR_syscall_max __NR_move_pages
+
+#ifdef __KERNEL__
 #include <linux/err.h>
+#endif
 
 #ifndef __NO_STUBS
 
@@ -663,8 +664,6 @@ do { \
 #define __ARCH_WANT_SYS_TIME
 #define __ARCH_WANT_COMPAT_SYS_TIME
 
-#ifndef __KERNEL_SYSCALLS__
-
 #define __syscall "syscall"
 
 #define _syscall0(type,name) \
@@ -746,83 +745,7 @@ __asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; movq %7,%%r9 ; " __syscall \
 __syscall_return(type,__res); \
 }
 
-#else /* __KERNEL_SYSCALLS__ */
-
-#include <linux/syscalls.h>
-#include <asm/ptrace.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-
-static inline pid_t setsid(void)
-{
-       return sys_setsid();
-}
-
-static inline ssize_t write(unsigned int fd, char * buf, size_t count)
-{
-       return sys_write(fd, buf, count);
-}
-
-static inline ssize_t read(unsigned int fd, char * buf, size_t count)
-{
-       return sys_read(fd, buf, count);
-}
-
-static inline off_t lseek(unsigned int fd, off_t offset, unsigned int origin)
-{
-       return sys_lseek(fd, offset, origin);
-}
-
-static inline long dup(unsigned int fd)
-{
-       return sys_dup(fd);
-}
-
-/* implemented in asm in arch/x86_64/kernel/entry.S */
-extern int execve(const char *, char * const *, char * const *);
-
-static inline long open(const char * filename, int flags, int mode)
-{
-       return sys_open(filename, flags, mode);
-}
-
-static inline long close(unsigned int fd)
-{
-       return sys_close(fd);
-}
-
-static inline pid_t waitpid(int pid, int * wait_stat, int flags)
-{
-       return sys_wait4(pid, wait_stat, flags, NULL);
-}
-
-extern long sys_mmap(unsigned long addr, unsigned long len,
-                       unsigned long prot, unsigned long flags,
-                       unsigned long fd, unsigned long off);
-
-extern int sys_modify_ldt(int func, void *ptr, unsigned long bytecount);
-
-asmlinkage long sys_execve(char *name, char **argv, char **envp,
-                       struct pt_regs regs);
-asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp,
-                       void *parent_tid, void *child_tid,
-                       struct pt_regs regs);
-asmlinkage long sys_fork(struct pt_regs regs);
-asmlinkage long sys_vfork(struct pt_regs regs);
-asmlinkage long sys_pipe(int *fildes);
-
+#ifdef __KERNEL__
 #ifndef __ASSEMBLY__
 
 #include <linux/linkage.h>
@@ -839,8 +762,8 @@ asmlinkage long sys_rt_sigaction(int sig,
                                size_t sigsetsize);
 
 #endif  /* __ASSEMBLY__ */
-
-#endif /* __KERNEL_SYSCALLS__ */
+#endif /* __KERNEL__ */
+#endif /* __NO_STUBS */
 
 /*
  * "Conditional" syscalls
@@ -850,8 +773,4 @@ asmlinkage long sys_rt_sigaction(int sig,
  */
 #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
 
-#endif /* __NO_STUBS */
-
-#endif /* __KERNEL__ */
-
 #endif /* _ASM_X86_64_UNISTD_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 5e1b99dc4ab3bfd93b3657182e9d43a960b19e11..411f810a55c604e0e5e5e77eede58f69dab8ddd8 100644 (file)
@@ -402,11 +402,6 @@ __asm__ __volatile__ ( \
 __syscall_return(type,__res); \
 }
 
-
-#ifdef __KERNEL_SYSCALLS__
-static __inline__ _syscall3(int,execve,const char*,file,char**,argv,char**,envp)
-#endif
-
 /*
  * "Conditional" syscalls
  *
index 15667cc947d58d0da5fc628c89f82271ebbdadc2..ea005c0a79fdecd0e61d9717aecb19bf86367262 100644 (file)
@@ -158,12 +158,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
@@ -337,6 +335,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 9760753e662b4f735583034b17a1e0ed5c24dc07..ef5cd192784c23bc326531660184c2098f930736 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <asm/compat.h>
 #include <asm/siginfo.h>
+#include <asm/signal.h>
 
 #define compat_jiffies_to_clock_t(x)   \
                (((unsigned long)(x) * COMPAT_USER_HZ) / HZ)
@@ -227,6 +228,7 @@ static inline int compat_timespec_compare(struct compat_timespec *lhs,
 asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp);
 
 extern int compat_printk(const char *fmt, ...);
+extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
 
 #endif /* CONFIG_COMPAT */
 #endif /* _LINUX_COMPAT_H */
index d5b7abc4f409c34ea3e2af5a79369c1e52d7ede0..4e1663d7691e4a44c676a446d2c94374963656b3 100644 (file)
@@ -122,10 +122,10 @@ COMPATIBLE_IOCTL(PROTECT_ARRAY)
 ULONG_IOCTL(HOT_ADD_DISK)
 ULONG_IOCTL(SET_DISK_FAULTY)
 COMPATIBLE_IOCTL(RUN_ARRAY)
-ULONG_IOCTL(START_ARRAY)
 COMPATIBLE_IOCTL(STOP_ARRAY)
 COMPATIBLE_IOCTL(STOP_ARRAY_RO)
 COMPATIBLE_IOCTL(RESTART_ARRAY_RW)
+ULONG_IOCTL(SET_BITMAP_FILE)
 /* DM */
 COMPATIBLE_IOCTL(DM_VERSION_32)
 COMPATIBLE_IOCTL(DM_REMOVE_ALL_32)
index 76a1807726eb0fb24b668995eb3bd5388c3e1013..7d0420274de00d26b86d6d986631860bb158d5d3 100644 (file)
@@ -129,6 +129,9 @@ static inline void suspend_console(void) {}
 static inline void resume_console(void) {}
 #endif /* CONFIG_DISABLE_CONSOLE_SUSPEND */
 
+int mda_console_init(void);
+void prom_con_init(void);
+
 /* Some debug stub to catch some of the obvious races in the VT code */
 #if 1
 #define WARN_CONSOLE_UNLOCKED()        WARN_ON(!is_console_locked() && !oops_in_progress)
index 25423f79bf9f95fbedc359de9aced4d4c99d1c23..ed6c0fee1ac76fa5af1e0ed27c26a6b6fbc86395 100644 (file)
@@ -54,7 +54,7 @@ struct vc_data {
        struct tty_struct *vc_tty;              /* TTY we are attached to */
        /* data for manual vt switching */
        struct vt_mode  vt_mode;
-       int             vt_pid;
+       struct pid      *vt_pid;
        int             vt_newvt;
        wait_queue_head_t paste_wait;
        /* mode flags */
index 65842efc1b70fba98fdeaec9b3db88491dfe161f..82c9a1f11020b2ecfd1f3947d42ac6218b50a841 100644 (file)
@@ -13,3 +13,4 @@ struct vc_data;
 extern unsigned char inverse_translate(struct vc_data *conp, int glyph);
 extern unsigned short *set_translate(int m, struct vc_data *vc);
 extern int conv_uni_to_pc(struct vc_data *conp, long ucs);
+void console_map_init(void);
index 88dafa246d87a968b61163ad500dd7da2d5bb812..952bee79a8f30902328277a6d16920a53e4da12f 100644 (file)
@@ -43,6 +43,8 @@ extern int debug_locks_off(void);
 # define locking_selftest()    do { } while (0)
 #endif
 
+struct task_struct;
+
 #ifdef CONFIG_LOCKDEP
 extern void debug_show_all_locks(void);
 extern void debug_show_held_locks(struct task_struct *task);
index e3d1c33d155883797f41d33b0096e06329d8de82..03ef41c1eaac346b441a00a54048818b7f35c60f 100644 (file)
@@ -55,8 +55,10 @@ typedef int (*dm_endio_fn) (struct dm_target *ti,
                            struct bio *bio, int error,
                            union map_info *map_context);
 
+typedef void (*dm_flush_fn) (struct dm_target *ti);
 typedef void (*dm_presuspend_fn) (struct dm_target *ti);
 typedef void (*dm_postsuspend_fn) (struct dm_target *ti);
+typedef int (*dm_preresume_fn) (struct dm_target *ti);
 typedef void (*dm_resume_fn) (struct dm_target *ti);
 
 typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type,
@@ -64,8 +66,17 @@ typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type,
 
 typedef int (*dm_message_fn) (struct dm_target *ti, unsigned argc, char **argv);
 
+typedef int (*dm_ioctl_fn) (struct dm_target *ti, struct inode *inode,
+                           struct file *filp, unsigned int cmd,
+                           unsigned long arg);
+
 void dm_error(const char *message);
 
+/*
+ * Combine device limits.
+ */
+void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev);
+
 /*
  * Constructors should call these functions to ensure destination devices
  * are opened/closed correctly.
@@ -86,11 +97,14 @@ struct target_type {
        dm_dtr_fn dtr;
        dm_map_fn map;
        dm_endio_fn end_io;
+       dm_flush_fn flush;
        dm_presuspend_fn presuspend;
        dm_postsuspend_fn postsuspend;
+       dm_preresume_fn preresume;
        dm_resume_fn resume;
        dm_status_fn status;
        dm_message_fn message;
+       dm_ioctl_fn ioctl;
 };
 
 struct io_restrictions {
index 9623bb6250901d37e8cedfea42304b770cddc534..8853fc4d1c5ebcd3b4f56749208057935955a208 100644 (file)
@@ -285,9 +285,9 @@ typedef char ioctl_struct[308];
 #define DM_DEV_SET_GEOMETRY    _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
 
 #define DM_VERSION_MAJOR       4
-#define DM_VERSION_MINOR       7
+#define DM_VERSION_MINOR       10
 #define DM_VERSION_PATCHLEVEL  0
-#define DM_VERSION_EXTRA       "-ioctl (2006-06-24)"
+#define DM_VERSION_EXTRA       "-ioctl (2006-09-14)"
 
 /* Status bits */
 #define DM_READONLY_FLAG       (1 << 0) /* In/Out */
index 2f335e966011510df9944119d33daae9850580aa..3e69241e6a81484a993a19566197abc8f19de0e8 100644 (file)
@@ -2,6 +2,7 @@
 #define _LINUX_FB_H
 
 #include <asm/types.h>
+#include <linux/i2c.h>
 
 /* Definitions of frame buffers                                                */
 
@@ -775,6 +776,7 @@ struct fb_info {
        struct fb_ops *fbops;
        struct device *device;
        struct class_device *class_device; /* sysfs per device attrs */
+       int class_flag;                    /* private sysfs flags */
 #ifdef CONFIG_FB_TILEBLITTING
        struct fb_tile_ops *tileops;    /* Tile Blitting */
 #endif
@@ -940,6 +942,7 @@ extern void fb_edid_to_monspecs(unsigned char *edid,
                                struct fb_monspecs *specs);
 extern void fb_destroy_modedb(struct fb_videomode *modedb);
 extern int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb);
+extern unsigned char *fb_ddc_read(struct i2c_adapter *adapter);
 
 /* drivers/video/modedb.c */
 #define VESA_MODEDB_SIZE 34
index bc0e645abb8078995ecd044e25ea462e413138be..34406ed467c352c4ac4ad67b490c0729107c967d 100644 (file)
@@ -686,7 +686,8 @@ extern struct block_device *I_BDEV(struct inode *inode);
 
 struct fown_struct {
        rwlock_t lock;          /* protects pid, uid, euid fields */
-       int pid;                /* pid or -pgrp where SIGIO should be sent */
+       struct pid *pid;        /* pid or -pgrp where SIGIO should be sent */
+       enum pid_type pid_type; /* Kind of process group SIGIO should be sent to */
        uid_t uid, euid;        /* uid/euid of process setting the owner */
        int signum;             /* posix.1b rt signal to be delivered on IO */
 };
@@ -882,8 +883,10 @@ extern void kill_fasync(struct fasync_struct **, int, int);
 /* only for net: no internal synchronization */
 extern void __kill_fasync(struct fasync_struct *, int, int);
 
+extern int __f_setown(struct file *filp, struct pid *, enum pid_type, int force);
 extern int f_setown(struct file *filp, unsigned long arg, int force);
 extern void f_delown(struct file *filp);
+extern pid_t f_getown(struct file *filp);
 extern int send_sigurg(struct fown_struct *fown);
 
 /*
@@ -1048,7 +1051,7 @@ int generic_osync_inode(struct inode *, struct address_space *, int);
  * This allows the kernel to read directories into kernel space or
  * to have different dirent layouts depending on the binary type.
  */
-typedef int (*filldir_t)(void *, const char *, int, loff_t, ino_t, unsigned);
+typedef int (*filldir_t)(void *, const char *, int, loff_t, u64, unsigned);
 
 struct block_device_operations {
        int (*open) (struct inode *, struct file *);
@@ -1522,6 +1525,9 @@ extern const struct file_operations def_fifo_fops;
 #ifdef CONFIG_BLOCK
 extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long);
 extern int blkdev_ioctl(struct inode *, struct file *, unsigned, unsigned long);
+extern int blkdev_driver_ioctl(struct inode *inode, struct file *file,
+                              struct gendisk *disk, unsigned cmd,
+                              unsigned long arg);
 extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long);
 extern int blkdev_get(struct block_device *, mode_t, unsigned);
 extern int blkdev_put(struct block_device *);
index 74ed35a00a94db84cefdc6ddcf62715582d6006a..543cd3cd9e779eb3694bbb74ecbd585c0e14e921 100644 (file)
@@ -55,6 +55,30 @@ static inline int fs_get_scc_index(enum fs_id id)
        return -1;
 }
 
+static inline int fs_fec_index2id(int index)
+{
+       int id = fsid_fec1 + index - 1;
+       if (id >= fsid_fec1 && id <= fsid_fec2)
+               return id;
+       return FS_MAX_INDEX;
+               }
+
+static inline int fs_fcc_index2id(int index)
+{
+       int id = fsid_fcc1 + index - 1;
+       if (id >= fsid_fcc1 && id <= fsid_fcc3)
+               return id;
+       return FS_MAX_INDEX;
+}
+
+static inline int fs_scc_index2id(int index)
+{
+       int id = fsid_scc1 + index - 1;
+       if (id >= fsid_scc1 && id <= fsid_scc4)
+               return id;
+       return FS_MAX_INDEX;
+}
+
 enum fs_mii_method {
        fsmii_fixed,
        fsmii_fec,
@@ -87,18 +111,21 @@ struct fs_mii_bb_platform_info {
 };
 
 struct fs_platform_info {
-       
-       void(*init_ioports)(void);
+
+       void(*init_ioports)(struct fs_platform_info *);
        /* device specific information */
        int fs_no;              /* controller index            */
+       char fs_type[4];        /* controller type             */
 
        u32 cp_page;            /* CPM page */
        u32 cp_block;           /* CPM sblock */
-       
+
        u32 clk_trx;            /* some stuff for pins & mux configuration*/
+       u32 clk_rx;
+       u32 clk_tx;
        u32 clk_route;
        u32 clk_mask;
-       
+
        u32 mem_offset;
        u32 dpram_offset;
        u32 fcc_regs_c;
@@ -124,4 +151,16 @@ struct fs_mii_fec_platform_info {
        u32 irq[32];
        u32 mii_speed;
 };
+
+static inline int fs_get_id(struct fs_platform_info *fpi)
+{
+       if(strstr(fpi->fs_type, "SCC"))
+               return fs_scc_index2id(fpi->fs_no);
+       if(strstr(fpi->fs_type, "FCC"))
+               return fs_fcc_index2id(fpi->fs_no);
+       if(strstr(fpi->fs_type, "FEC"))
+               return fs_fec_index2id(fpi->fs_no);
+       return fpi->fs_no;
+}
+
 #endif
index f5975126b712261fc12e62c101630fe4856d1dde..809bb9ffc78846fbc2f8b5747ef42b225d8c4940 100644 (file)
@@ -46,15 +46,27 @@ static inline int fs_uart_id_fsid2smc(int id)
 }
 
 struct fs_uart_platform_info {
-        void(*init_ioports)(void);
+        void(*init_ioports)(struct fs_uart_platform_info *);
        /* device specific information */
        int fs_no;              /* controller index */
+       char fs_type[4];        /* controller type  */
        u32 uart_clk;
        u8 tx_num_fifo;
        u8 tx_buf_size;
        u8 rx_num_fifo;
        u8 rx_buf_size;
        u8 brg;
+       u8 clk_rx;
+       u8 clk_tx;
 };
 
+static inline int fs_uart_get_id(struct fs_uart_platform_info *fpi)
+{
+        if(strstr(fpi->fs_type, "SMC"))
+                return fs_uart_id_smc2fsid(fpi->fs_no);
+        if(strstr(fpi->fs_type, "SCC"))
+                return fs_uart_id_scc2fsid(fpi->fs_no);
+        return fpi->fs_no;
+}
+
 #endif
index 16fbe59edeb1853958afacdfee91981195adf124..3da29e2d524a57a8bc5fe80cc9942da561c1f32b 100644 (file)
 
 struct gianfar_platform_data {
        /* device specific information */
-       u32 device_flags;
-
+       u32     device_flags;
        /* board specific information */
-       u32 board_flags;
-       u32 bus_id;
-       u32 phy_id;
-       u8 mac_addr[6];
+       u32     board_flags;
+       u32     bus_id;
+       u32     phy_id;
+       u8      mac_addr[6];
 };
 
 struct gianfar_mdio_data {
        /* board specific information */
-       int irq[32];
+       int     irq[32];
 };
 
 /* Flags related to gianfar device features */
@@ -76,14 +75,13 @@ struct gianfar_mdio_data {
 
 struct fsl_i2c_platform_data {
        /* device specific information */
-       u32 device_flags;
+       u32     device_flags;
 };
 
 /* Flags related to I2C device features */
 #define FSL_I2C_DEV_SEPARATE_DFSRR     0x00000001
 #define FSL_I2C_DEV_CLOCK_5200         0x00000002
 
-
 enum fsl_usb2_operating_modes {
        FSL_USB2_MPH_HOST,
        FSL_USB2_DR_HOST,
@@ -101,9 +99,9 @@ enum fsl_usb2_phy_modes {
 
 struct fsl_usb2_platform_data {
        /* board specific information */
-       enum fsl_usb2_operating_modes operating_mode;
-       enum fsl_usb2_phy_modes phy_mode;
-       unsigned int port_enables;
+       enum fsl_usb2_operating_modes   operating_mode;
+       enum fsl_usb2_phy_modes         phy_mode;
+       unsigned int                    port_enables;
 };
 
 /* Flags in fsl_usb2_mph_platform_data */
@@ -121,5 +119,44 @@ struct fsl_spi_platform_data {
        u32     sysclk;
 };
 
-#endif                         /* _FSL_DEVICE_H_ */
-#endif                         /* __KERNEL__ */
+/* Ethernet interface (phy management and speed)
+*/
+enum enet_interface {
+       ENET_10_MII,            /* 10 Base T,   MII interface */
+       ENET_10_RMII,           /* 10 Base T,  RMII interface */
+       ENET_10_RGMII,          /* 10 Base T, RGMII interface */
+       ENET_100_MII,           /* 100 Base T,   MII interface */
+       ENET_100_RMII,          /* 100 Base T,  RMII interface */
+       ENET_100_RGMII,         /* 100 Base T, RGMII interface */
+       ENET_1000_GMII,         /* 1000 Base T,  GMII interface */
+       ENET_1000_RGMII,        /* 1000 Base T, RGMII interface */
+       ENET_1000_TBI,          /* 1000 Base T,   TBI interface */
+       ENET_1000_RTBI          /* 1000 Base T,  RTBI interface */
+};
+
+struct ucc_geth_platform_data {
+       /* device specific information */
+       u32                     device_flags;
+       u32                     phy_reg_addr;
+
+       /* board specific information */
+       u32                     board_flags;
+       u8                      rx_clock;
+       u8                      tx_clock;
+       u32                     phy_id;
+       enum enet_interface     phy_interface;
+       u32                     phy_interrupt;
+       u8                      mac_addr[6];
+};
+
+/* Flags related to UCC Gigabit Ethernet device features */
+#define FSL_UGETH_DEV_HAS_GIGABIT              0x00000001
+#define FSL_UGETH_DEV_HAS_COALESCE             0x00000002
+#define FSL_UGETH_DEV_HAS_RMON                 0x00000004
+
+/* Flags in ucc_geth_platform_data */
+#define FSL_UGETH_BRD_HAS_PHY_INTR             0x00000001
+                               /* if not set use a timer */
+
+#endif /* _FSL_DEVICE_H_ */
+#endif /* __KERNEL__ */
index 690c42803d2e7d310e7bd59cbac2abebaa263098..9869ef3674acbfe0f1a8fbad4fd20286c092c3be 100644 (file)
@@ -31,5 +31,6 @@ struct gen_pool_chunk {
 
 extern struct gen_pool *gen_pool_create(int, int);
 extern int gen_pool_add(struct gen_pool *, unsigned long, size_t, int);
+extern void gen_pool_destroy(struct gen_pool *);
 extern unsigned long gen_pool_alloc(struct gen_pool *, size_t);
 extern void gen_pool_free(struct gen_pool *, unsigned long, size_t);
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 99620451d958730a7754cf80acf572a770d75e40..07d8d725541fa5c9b26d312671fcd8b974329190 100644 (file)
@@ -251,7 +251,8 @@ static inline void ide_std_init_ports(hw_regs_t *hw,
 
 #include <asm/ide.h>
 
-#ifndef MAX_HWIFS
+#if !defined(MAX_HWIFS) || defined(CONFIG_EMBEDDED)
+#undef MAX_HWIFS
 #define MAX_HWIFS      CONFIG_IDE_MAX_HWIFS
 #endif
 
@@ -773,12 +774,13 @@ typedef struct hwif_s {
        unsigned long   dma_status;     /* dma status register */
        unsigned long   dma_vendor3;    /* dma vendor 3 register */
        unsigned long   dma_prdtable;   /* actual prd table address */
-       unsigned long   dma_base2;      /* extended base addr for dma ports */
 
-       unsigned        dma_extra;      /* extra addr for dma ports */
        unsigned long   config_data;    /* for use by chipset-specific code */
        unsigned long   select_data;    /* for use by chipset-specific code */
 
+       unsigned long   extra_base;     /* extra addr for dma ports */
+       unsigned        extra_ports;    /* number of extra dma ports */
+
        unsigned        noprobe    : 1; /* don't probe for this interface */
        unsigned        present    : 1; /* this interface exists */
        unsigned        hold       : 1; /* this interface is always present */
@@ -823,6 +825,9 @@ typedef struct hwgroup_s {
        unsigned int sleeping   : 1;
                /* BOOL: polling active & poll_timeout field valid */
        unsigned int polling    : 1;
+               /* BOOL: in a polling reset situation. Must not trigger another reset yet */
+       unsigned int resetting  : 1;
+
                /* current drive */
        ide_drive_t *drive;
                /* ptr to current hwif in linked-list */
@@ -1190,7 +1195,6 @@ extern int ideprobe_init(void);
 extern void ide_scan_pcibus(int scan_direction) __init;
 extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *owner);
 #define ide_pci_register_driver(d) __ide_pci_register_driver(d, THIS_MODULE)
-extern void ide_pci_unregister_driver(struct pci_driver *driver);
 void ide_pci_setup_ports(struct pci_dev *, struct ide_pci_device_s *, int, ata_index_t *);
 extern void ide_setup_pci_noise (struct pci_dev *dev, struct ide_pci_device_s *d);
 
index d79fc75fa7c2c3d86dbf0c38f1834bc437aa524a..2619859f6e1b35c487244e5098abf83dbb6d3d1b 100644 (file)
@@ -40,6 +40,7 @@ enum {
 
   IPPROTO_ESP = 50,            /* Encapsulation Security Payload protocol */
   IPPROTO_AH = 51,             /* Authentication Header protocol       */
+  IPPROTO_BEETPH = 94,        /* IP option pseudo header for BEET */
   IPPROTO_PIM    = 103,                /* Protocol Independent Multicast       */
 
   IPPROTO_COMP   = 108,                /* Compression Header protocol */
index 60aac2cea0cf63764b26d09f1f05cbc88b53e7ee..33c5daacc74338dd0d479f976892659ab308eab8 100644 (file)
@@ -4,7 +4,9 @@
 #include <linux/file.h>
 #include <linux/rcupdate.h>
 #include <linux/irqflags.h>
+#include <linux/utsname.h>
 #include <linux/lockdep.h>
+#include <linux/ipc.h>
 
 #define INIT_FDTABLE \
 {                                                      \
        .session        = 1,                                            \
 }
 
+extern struct nsproxy init_nsproxy;
+#define INIT_NSPROXY(nsproxy) {                                                \
+       .count          = ATOMIC_INIT(1),                               \
+       .nslock         = SPIN_LOCK_UNLOCKED,                           \
+       .uts_ns         = &init_uts_ns,                                 \
+       .namespace      = NULL,                                         \
+       INIT_IPC_NS(ipc_ns)                                             \
+}
+
 #define INIT_SIGHAND(sighand) {                                                \
        .count          = ATOMIC_INIT(1),                               \
        .action         = { { { .sa_handler = NULL, } }, },             \
@@ -117,6 +128,7 @@ extern struct group_info init_groups;
        .files          = &init_files,                                  \
        .signal         = &init_signals,                                \
        .sighand        = &init_sighand,                                \
+       .nsproxy        = &init_nsproxy,                                \
        .pending        = {                                             \
                .list = LIST_HEAD_INIT(tsk.pending.list),               \
                .signal = {{0}}},                                       \
index b3253ab72ff7da2914e225550d1a0c3db42b6d8d..5770105471dd359eb2e2b46c70f510e4c2eac35b 100644 (file)
@@ -349,6 +349,9 @@ struct input_absinfo {
 
 #define KEY_BATTERY            236
 
+#define KEY_BLUETOOTH          237
+#define KEY_WLAN               238
+
 #define KEY_UNKNOWN            240
 
 #define BTN_MISC               0x100
@@ -645,6 +648,7 @@ struct input_absinfo {
 #define BUS_USB                        0x03
 #define BUS_HIL                        0x04
 #define BUS_BLUETOOTH          0x05
+#define BUS_VIRTUAL            0x06
 
 #define BUS_ISA                        0x10
 #define BUS_I8042              0x11
@@ -667,98 +671,167 @@ struct input_absinfo {
 
 /*
  * Structures used in ioctls to upload effects to a device
- * The first structures are not passed directly by using ioctls.
- * They are sub-structures of the actually sent structure (called ff_effect)
+ * They are pieces of a bigger structure (called ff_effect)
+ */
+
+/*
+ * All duration values are expressed in ms. Values above 32767 ms (0x7fff)
+ * should not be used and have unspecified results.
  */
 
+/**
+ * struct ff_replay - defines scheduling of the effect
+ * @length: duration of the effect
+ * @delay: delay before effect should start playing
+ */
 struct ff_replay {
-       __u16 length; /* Duration of an effect in ms. All other times are also expressed in ms */
-       __u16 delay;  /* Time to wait before to start playing an effect */
+       __u16 length;
+       __u16 delay;
 };
 
+/**
+ * struct ff_trigger - defines what triggers the effect
+ * @button: number of the button triggering the effect
+ * @interval: controls how soon the effect can be re-triggered
+ */
 struct ff_trigger {
-       __u16 button;   /* Number of button triggering an effect */
-       __u16 interval; /* Time to wait before an effect can be re-triggered (ms) */
+       __u16 button;
+       __u16 interval;
 };
 
+/**
+ * struct ff_envelope - generic effect envelope
+ * @attack_length: duration of the attack (ms)
+ * @attack_level: level at the beginning of the attack
+ * @fade_length: duration of fade (ms)
+ * @fade_level: level at the end of fade
+ *
+ * The @attack_level and @fade_level are absolute values; when applying
+ * envelope force-feedback core will convert to positive/negative
+ * value based on polarity of the default level of the effect.
+ * Valid range for the attack and fade levels is 0x0000 - 0x7fff
+ */
 struct ff_envelope {
-       __u16 attack_length;    /* Duration of attack (ms) */
-       __u16 attack_level;     /* Level at beginning of attack */
-       __u16 fade_length;      /* Duration of fade (ms) */
-       __u16 fade_level;       /* Level at end of fade */
+       __u16 attack_length;
+       __u16 attack_level;
+       __u16 fade_length;
+       __u16 fade_level;
 };
 
-/* FF_CONSTANT */
+/**
+ * struct ff_constant_effect - defines parameters of a constant effect
+ * @level: strength of the effect; may be negative
+ * @envelope: envelope data
+ */
 struct ff_constant_effect {
-       __s16 level;        /* Strength of effect. Negative values are OK */
+       __s16 level;
        struct ff_envelope envelope;
 };
 
-/* FF_RAMP */
+/**
+ * struct ff_ramp_effect - defines parameters of a ramp effect
+ * @start_level: beginning strength of the effect; may be negative
+ * @end_level: final strength of the effect; may be negative
+ * @envelope: envelope data
+ */
 struct ff_ramp_effect {
        __s16 start_level;
        __s16 end_level;
        struct ff_envelope envelope;
 };
 
-/* FF_SPRING of FF_FRICTION */
+/**
+ * struct ff_condition_effect - defines a spring or friction effect
+ * @right_saturation: maximum level when joystick moved all way to the right
+ * @left_saturation: same for the left side
+ * @right_coeff: controls how fast the force grows when the joystick moves
+ *     to the right
+ * @left_coeff: same for the left side
+ * @deadband: size of the dead zone, where no force is produced
+ * @center: position of the dead zone
+ */
 struct ff_condition_effect {
-       __u16 right_saturation; /* Max level when joystick is on the right */
-       __u16 left_saturation;  /* Max level when joystick in on the left */
-
-       __s16 right_coeff;      /* Indicates how fast the force grows when the
-                                  joystick moves to the right */
-       __s16 left_coeff;       /* Same for left side */
+       __u16 right_saturation;
+       __u16 left_saturation;
 
-       __u16 deadband; /* Size of area where no force is produced */
-       __s16 center;   /* Position of dead zone */
+       __s16 right_coeff;
+       __s16 left_coeff;
 
+       __u16 deadband;
+       __s16 center;
 };
 
-/* FF_PERIODIC */
+/**
+ * struct ff_periodic_effect - defines parameters of a periodic effect
+ * @waveform: kind of the effect (wave)
+ * @period: period of the wave (ms)
+ * @magnitude: peak value
+ * @offset: mean value of the wave (roughly)
+ * @phase: 'horizontal' shift
+ * @envelope: envelope data
+ * @custom_len: number of samples (FF_CUSTOM only)
+ * @custom_data: buffer of samples (FF_CUSTOM only)
+ *
+ * Known waveforms - FF_SQUARE, FF_TRIANGLE, FF_SINE, FF_SAW_UP,
+ * FF_SAW_DOWN, FF_CUSTOM. The exact syntax FF_CUSTOM is undefined
+ * for the time being as no driver supports it yet.
+ *
+ * Note: the data pointed by custom_data is copied by the driver.
+ * You can therefore dispose of the memory after the upload/update.
+ */
 struct ff_periodic_effect {
-       __u16 waveform; /* Kind of wave (sine, square...) */
-       __u16 period;   /* in ms */
-       __s16 magnitude;        /* Peak value */
-       __s16 offset;   /* Mean value of wave (roughly) */
-       __u16 phase;            /* 'Horizontal' shift */
+       __u16 waveform;
+       __u16 period;
+       __s16 magnitude;
+       __s16 offset;
+       __u16 phase;
 
        struct ff_envelope envelope;
 
-/* Only used if waveform == FF_CUSTOM */
-       __u32 custom_len;       /* Number of samples */
-       __s16 *custom_data;     /* Buffer of samples */
-/* Note: the data pointed by custom_data is copied by the driver. You can
- * therefore dispose of the memory after the upload/update */
+       __u32 custom_len;
+       __s16 *custom_data;
 };
 
-/* FF_RUMBLE */
-/* Some rumble pads have two motors of different weight.
-   strong_magnitude represents the magnitude of the vibration generated
-   by the heavy motor.
-*/
+/**
+ * struct ff_rumble_effect - defines parameters of a periodic effect
+ * @strong_magnitude: magnitude of the heavy motor
+ * @weak_magnitude: magnitude of the light one
+ *
+ * Some rumble pads have two motors of different weight. Strong_magnitude
+ * represents the magnitude of the vibration generated by the heavy one.
+ */
 struct ff_rumble_effect {
-       __u16 strong_magnitude;  /* Magnitude of the heavy motor */
-       __u16 weak_magnitude;    /* Magnitude of the light one */
+       __u16 strong_magnitude;
+       __u16 weak_magnitude;
 };
 
-/*
- * Structure sent through ioctl from the application to the driver
+/**
+ * struct ff_effect - defines force feedback effect
+ * @type: type of the effect (FF_CONSTANT, FF_PERIODIC, FF_RAMP, FF_SPRING,
+ *     FF_FRICTION, FF_DAMPER, FF_RUMBLE, FF_INERTIA, or FF_CUSTOM)
+ * @id: an unique id assigned to an effect
+ * @direction: direction of the effect
+ * @trigger: trigger conditions (struct ff_trigger)
+ * @replay: scheduling of the effect (struct ff_replay)
+ * @u: effect-specific structure (one of ff_constant_effect, ff_ramp_effect,
+ *     ff_periodic_effect, ff_condition_effect, ff_rumble_effect) further
+ *     defining effect parameters
+ *
+ * This structure is sent through ioctl from the application to the driver.
+ * To create a new effect aplication should set its @id to -1; the kernel
+ * will return assigned @id which can later be used to update or delete
+ * this effect.
+ *
+ * Direction of the effect is encoded as follows:
+ *     0 deg -> 0x0000 (down)
+ *     90 deg -> 0x4000 (left)
+ *     180 deg -> 0x8000 (up)
+ *     270 deg -> 0xC000 (right)
  */
 struct ff_effect {
        __u16 type;
-/* Following field denotes the unique id assigned to an effect.
- * If user sets if to -1, a new effect is created, and its id is returned in the same field
- * Else, the user sets it to the effect id it wants to update.
- */
        __s16 id;
-
-       __u16 direction;        /* Direction. 0 deg -> 0x0000 (down)
-                                            90 deg -> 0x4000 (left)
-                                           180 deg -> 0x8000 (up)
-                                           270 deg -> 0xC000 (right)
-                               */
-
+       __u16 direction;
        struct ff_trigger trigger;
        struct ff_replay replay;
 
@@ -784,6 +857,9 @@ struct ff_effect {
 #define FF_INERTIA     0x56
 #define FF_RAMP                0x57
 
+#define FF_EFFECT_MIN  FF_RUMBLE
+#define FF_EFFECT_MAX  FF_RAMP
+
 /*
  * Force feedback periodic effect types
  */
@@ -795,6 +871,9 @@ struct ff_effect {
 #define FF_SAW_DOWN    0x5c
 #define FF_CUSTOM      0x5d
 
+#define FF_WAVEFORM_MIN        FF_SQUARE
+#define FF_WAVEFORM_MAX        FF_CUSTOM
+
 /*
  * Set ff device properties
  */
@@ -864,12 +943,13 @@ struct input_dev {
        unsigned long sndbit[NBITS(SND_MAX)];
        unsigned long ffbit[NBITS(FF_MAX)];
        unsigned long swbit[NBITS(SW_MAX)];
-       int ff_effects_max;
 
        unsigned int keycodemax;
        unsigned int keycodesize;
        void *keycode;
 
+       struct ff_device *ff;
+
        unsigned int repeat_key;
        struct timer_list timer;
 
@@ -895,8 +975,6 @@ struct input_dev {
        void (*close)(struct input_dev *dev);
        int (*flush)(struct input_dev *dev, struct file *file);
        int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
-       int (*upload_effect)(struct input_dev *dev, struct ff_effect *effect);
-       int (*erase_effect)(struct input_dev *dev, int effect_id);
 
        struct input_handle *grab;
 
@@ -904,9 +982,6 @@ struct input_dev {
        unsigned int users;
 
        struct class_device cdev;
-       struct device *dev;     /* will be removed soon */
-
-       int dynalloc;   /* temporarily */
 
        struct list_head        h_list;
        struct list_head        node;
@@ -985,16 +1060,16 @@ struct input_handler {
        void *private;
 
        void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
-       struct input_handle* (*connect)(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id);
+       struct input_handle* (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);
        void (*disconnect)(struct input_handle *handle);
        void (*start)(struct input_handle *handle);
 
        const struct file_operations *fops;
        int minor;
-       char *name;
+       const char *name;
 
-       struct input_device_id *id_table;
-       struct input_device_id *blacklist;
+       const struct input_device_id *id_table;
+       const struct input_device_id *blacklist;
 
        struct list_head        h_list;
        struct list_head        node;
@@ -1005,7 +1080,7 @@ struct input_handle {
        void *private;
 
        int open;
-       char *name;
+       const char *name;
 
        struct input_dev *dev;
        struct input_handler *handler;
@@ -1019,12 +1094,6 @@ struct input_handle {
 #define to_handle(n) container_of(n,struct input_handle,d_node)
 #define to_handle_h(n) container_of(n,struct input_handle,h_node)
 
-static inline void init_input_dev(struct input_dev *dev)
-{
-       INIT_LIST_HEAD(&dev->h_list);
-       INIT_LIST_HEAD(&dev->node);
-}
-
 struct input_dev *input_allocate_device(void);
 void input_free_device(struct input_dev *dev);
 
@@ -1041,7 +1110,7 @@ static inline void input_put_device(struct input_dev *dev)
 int input_register_device(struct input_dev *);
 void input_unregister_device(struct input_dev *);
 
-void input_register_handler(struct input_handler *);
+int input_register_handler(struct input_handler *);
 void input_unregister_handler(struct input_handler *);
 
 int input_grab_device(struct input_handle *);
@@ -1070,11 +1139,6 @@ static inline void input_report_abs(struct input_dev *dev, unsigned int code, in
        input_event(dev, EV_ABS, code, value);
 }
 
-static inline void input_report_ff(struct input_dev *dev, unsigned int code, int value)
-{
-       input_event(dev, EV_FF, code, value);
-}
-
 static inline void input_report_ff_status(struct input_dev *dev, unsigned int code, int value)
 {
        input_event(dev, EV_FF_STATUS, code, value);
@@ -1108,5 +1172,61 @@ static inline void input_set_abs_params(struct input_dev *dev, int axis, int min
 
 extern struct class input_class;
 
+/**
+ * struct ff_device - force-feedback part of an input device
+ * @upload: Called to upload an new effect into device
+ * @erase: Called to erase an effect from device
+ * @playback: Called to request device to start playing specified effect
+ * @set_gain: Called to set specified gain
+ * @set_autocenter: Called to auto-center device
+ * @destroy: called by input core when parent input device is being
+ *     destroyed
+ * @private: driver-specific data, will be freed automatically
+ * @ffbit: bitmap of force feedback capabilities truly supported by
+ *     device (not emulated like ones in input_dev->ffbit)
+ * @mutex: mutex for serializing access to the device
+ * @max_effects: maximum number of effects supported by device
+ * @effects: pointer to an array of effects currently loaded into device
+ * @effect_owners: array of effect owners; when file handle owning
+ *     an effect gets closed the effcet is automatically erased
+ *
+ * Every force-feedback device must implement upload() and playback()
+ * methods; erase() is optional. set_gain() and set_autocenter() need
+ * only be implemented if driver sets up FF_GAIN and FF_AUTOCENTER
+ * bits.
+ */
+struct ff_device {
+       int (*upload)(struct input_dev *dev, struct ff_effect *effect,
+                     struct ff_effect *old);
+       int (*erase)(struct input_dev *dev, int effect_id);
+
+       int (*playback)(struct input_dev *dev, int effect_id, int value);
+       void (*set_gain)(struct input_dev *dev, u16 gain);
+       void (*set_autocenter)(struct input_dev *dev, u16 magnitude);
+
+       void (*destroy)(struct ff_device *);
+
+       void *private;
+
+       unsigned long ffbit[NBITS(FF_MAX)];
+
+       struct mutex mutex;
+
+       int max_effects;
+       struct ff_effect *effects;
+       struct file *effect_owners[];
+};
+
+int input_ff_create(struct input_dev *dev, int max_effects);
+void input_ff_destroy(struct input_dev *dev);
+
+int input_ff_event(struct input_dev *dev, unsigned int type, unsigned int code, int value);
+
+int input_ff_upload(struct input_dev *dev, struct ff_effect *effect, struct file *file);
+int input_ff_erase(struct input_dev *dev, int effect_id, struct file *file);
+
+int input_ff_create_memless(struct input_dev *dev, void *data,
+               int (*play_effect)(struct input_dev *, void *, struct ff_effect *));
+
 #endif
 #endif
index 6b25d36fc54c481779a0d15b708e9bcca9c713a4..ecee9bb27d0e6db993778bb6b82169fd5b8cf8d2 100644 (file)
@@ -80,6 +80,8 @@
 #define        IPOPT_TS_TSANDADDR      1               /* timestamps and addresses */
 #define        IPOPT_TS_PRESPEC        3               /* specified modules only */
 
+#define IPV4_BEET_PHMAXLEN 8
+
 struct iphdr {
 #if defined(__LITTLE_ENDIAN_BITFIELD)
        __u8    ihl:4,
@@ -123,4 +125,11 @@ struct ip_comp_hdr {
        __be16 cpi;
 };
 
+struct ip_beet_phdr {
+       __u8 nexthdr;
+       __u8 hdrlen;
+       __u8 padlen;
+       __u8 reserved;
+};
+
 #endif /* _LINUX_IP_H */
index b291189737e747178b664d1d312e8b737442d790..636094c29b167e185168d10882fd2c497903d166 100644 (file)
@@ -51,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 */
@@ -68,6 +70,59 @@ struct kern_ipc_perm
        void            *security;
 };
 
+struct ipc_ids;
+struct ipc_namespace {
+       struct kref     kref;
+       struct ipc_ids  *ids[3];
+
+       int             sem_ctls[4];
+       int             used_sems;
+
+       int             msg_ctlmax;
+       int             msg_ctlmnb;
+       int             msg_ctlmni;
+
+       size_t          shm_ctlmax;
+       size_t          shm_ctlall;
+       int             shm_ctlmni;
+       int             shm_tot;
+};
+
+extern struct ipc_namespace init_ipc_ns;
+
+#ifdef CONFIG_SYSVIPC
+#define INIT_IPC_NS(ns)                .ns             = &init_ipc_ns,
+#else
+#define INIT_IPC_NS(ns)
+#endif
+
+#ifdef CONFIG_IPC_NS
+extern void free_ipc_ns(struct kref *kref);
+extern int copy_ipcs(unsigned long flags, struct task_struct *tsk);
+extern int unshare_ipcs(unsigned long flags, struct ipc_namespace **ns);
+#else
+static inline int copy_ipcs(unsigned long flags, struct task_struct *tsk)
+{
+       return 0;
+}
+#endif
+
+static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)
+{
+#ifdef CONFIG_IPC_NS
+       if (ns)
+               kref_get(&ns->kref);
+#endif
+       return ns;
+}
+
+static inline void put_ipc_ns(struct ipc_namespace *ns)
+{
+#ifdef CONFIG_IPC_NS
+       kref_put(&ns->kref, free_ipc_ns);
+#endif
+}
+
 #endif /* __KERNEL__ */
 
 #endif /* _LINUX_IPC_H */
index d3c527616b5e98c566a9b00907411a961239e5e6..d17a6302a0e96637e1e543a6c25fb4f23d6691e4 100644 (file)
@@ -12,7 +12,8 @@
 enum {
        IPSEC_MODE_ANY          = 0,    /* We do not support this for SA */
        IPSEC_MODE_TRANSPORT    = 1,
-       IPSEC_MODE_TUNNEL       = 2
+       IPSEC_MODE_TUNNEL       = 2,
+       IPSEC_MODE_BEET         = 3
 };
 
 enum {
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);
diff --git a/include/linux/ite_gpio.h b/include/linux/ite_gpio.h
deleted file mode 100644 (file)
index b123a14..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * FILE NAME ite_gpio.h
- *
- * BRIEF MODULE DESCRIPTION
- *     Generic gpio.
- *
- *  Author: MontaVista Software, Inc.  <source@mvista.com>
- *          Hai-Pao Fan <haipao@mvista.com>
- *
- * Copyright 2001 MontaVista Software Inc.
- *
- *  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.
- */
-
-#ifndef __ITE_GPIO_H
-#define __ITE_GPIO_H
-
-#include <linux/ioctl.h>
-
-struct ite_gpio_ioctl_data {
-       __u32 device;
-       __u32 mask;
-       __u32 data;
-};
-
-#define ITE_GPIO_IOCTL_BASE    'Z'
-
-#define ITE_GPIO_IN            _IOWR(ITE_GPIO_IOCTL_BASE, 0, struct ite_gpio_ioctl_data)
-#define ITE_GPIO_OUT           _IOW (ITE_GPIO_IOCTL_BASE, 1, struct ite_gpio_ioctl_data)
-#define        ITE_GPIO_INT_CTRL       _IOW (ITE_GPIO_IOCTL_BASE, 2, struct ite_gpio_ioctl_data)
-#define        ITE_GPIO_IN_STATUS      _IOW (ITE_GPIO_IOCTL_BASE, 3, struct ite_gpio_ioctl_data)
-#define        ITE_GPIO_OUT_STATUS     _IOW (ITE_GPIO_IOCTL_BASE, 4, struct ite_gpio_ioctl_data)
-#define ITE_GPIO_GEN_CTRL      _IOW (ITE_GPIO_IOCTL_BASE, 5, struct ite_gpio_ioctl_data)
-#define ITE_GPIO_INT_WAIT      _IOW (ITE_GPIO_IOCTL_BASE, 6, struct ite_gpio_ioctl_data)
-
-#define        ITE_GPIO_PORTA  0x01
-#define        ITE_GPIO_PORTB  0x02
-#define        ITE_GPIO_PORTC  0x04
-
-extern int ite_gpio_in(__u32 device, __u32 mask, volatile __u32 *data);
-extern int ite_gpio_out(__u32 device, __u32 mask, __u32 data);
-extern int ite_gpio_int_ctrl(__u32 device, __u32 mask, __u32 data);
-extern int ite_gpio_in_status(__u32 device, __u32 mask, volatile __u32 *data);
-extern int ite_gpio_out_status(__u32 device, __u32 mask, __u32 data);
-extern int ite_gpio_gen_ctrl(__u32 device, __u32 mask, __u32 data);
-extern int ite_gpio_int_wait(__u32 device, __u32 mask, __u32 data);
-
-#endif
index 849043ce4ed6ad811d77decf3463238a1c9a6f82..1cebcbc28b474d9f7af1d4061f0e30ba60347aa8 100644 (file)
 /* Lookup the address for a symbol. Returns 0 if not found. */
 unsigned long kallsyms_lookup_name(const char *name);
 
+extern int kallsyms_lookup_size_offset(unsigned long addr,
+                                 unsigned long *symbolsize,
+                                 unsigned long *offset);
+
 /* Lookup an address.  modname is set to NULL if it's in the kernel. */
 const char *kallsyms_lookup(unsigned long addr,
                            unsigned long *symbolsize,
@@ -28,6 +32,13 @@ static inline unsigned long kallsyms_lookup_name(const char *name)
        return 0;
 }
 
+static inline int kallsyms_lookup_size_offset(unsigned long addr,
+                                             unsigned long *symbolsize,
+                                             unsigned long *offset)
+{
+       return 0;
+}
+
 static inline const char *kallsyms_lookup(unsigned long addr,
                                          unsigned long *symbolsize,
                                          unsigned long *offset,
index 4d00988dad039ebc5f871d6323b2b7d1676da9dc..80f39cab470a2800abd64994341f2daca6c66678 100644 (file)
@@ -216,8 +216,10 @@ extern void dump_stack(void);
 #define pr_debug(fmt,arg...) \
        printk(KERN_DEBUG fmt,##arg)
 #else
-#define pr_debug(fmt,arg...) \
-       do { } while (0)
+static inline int __attribute__ ((format (printf, 1, 2))) pr_debug(const char * fmt, ...)
+{
+       return 0;
+}
 #endif
 
 #define pr_info(fmt,arg...) \
index 8bf6702da2a0348e1ac3538ffba7f1954ceffc5b..ac4c0559f7510e16c8b2c6113964284f762fcc9d 100644 (file)
@@ -77,6 +77,12 @@ struct kprobe {
        /* location of the probe point */
        kprobe_opcode_t *addr;
 
+       /* Allow user to indicate symbol name of the probe point */
+       char *symbol_name;
+
+       /* Offset into the symbol */
+       unsigned int offset;
+
        /* Called before addr is executed. */
        kprobe_pre_handler_t pre_handler;
 
@@ -196,7 +202,7 @@ void unregister_kretprobe(struct kretprobe *rp);
 struct kretprobe_instance *get_free_rp_inst(struct kretprobe *rp);
 void add_rp_inst(struct kretprobe_instance *ri);
 void kprobe_flush_task(struct task_struct *tk);
-void recycle_rp_inst(struct kretprobe_instance *ri);
+void recycle_rp_inst(struct kretprobe_instance *ri, struct hlist_head *head);
 #else /* CONFIG_KPROBES */
 
 #define __kprobes      /**/
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 08a450a9dbf7dc77bd6788824e82a38f8d09e6e2..f6f301e2b0f58a5f229c62c826f810c8e1177431 100644 (file)
@@ -47,5 +47,6 @@ int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int comman
 int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data);
 int ps2_handle_response(struct ps2dev *ps2dev, unsigned char data);
 void ps2_cmd_aborted(struct ps2dev *ps2dev);
+int ps2_is_keyboard_id(char id);
 
 #endif /* _LIBPS2_H */
index b054debef2e0599f8b681690f2831589daa79bc5..81e3a185f9515ada07ef16bef6b94a619e9196f6 100644 (file)
@@ -30,7 +30,7 @@ extern struct nlmsvc_binding *        nlmsvc_ops;
  * Functions exported by the lockd module
  */
 extern int     nlmclnt_proc(struct inode *, int, struct file_lock *);
-extern int     lockd_up(void);
+extern int     lockd_up(int proto);
 extern void    lockd_down(void);
 
 #endif /* LINUX_LOCKD_BIND_H */
index 0d92c468d55aeeb1f4b83e5847ef3bc5c529b2b7..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 */
 };
 
 /*
@@ -80,7 +88,7 @@ struct nlm_wait;
 /*
  * Memory chunk for NLM client RPC request.
  */
-#define NLMCLNT_OHSIZE         (sizeof(system_utsname.nodename)+10)
+#define NLMCLNT_OHSIZE         (sizeof(utsname()->nodename)+10)
 struct nlm_rqst {
        unsigned int            a_flags;        /* initial RPC task flags */
        struct nlm_host *       a_host;         /* host handle */
@@ -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
  *
index 2c599175c583c36a0bbd71528640489fceb6c149..4b2d8091a4104a0cd603d64a9240d6dbdf9b5396 100644 (file)
@@ -320,6 +320,8 @@ struct module
        /* Am I GPL-compatible */
        int license_gplok;
 
+       unsigned int taints;    /* same bits as kernel:tainted */
+
 #ifdef CONFIG_MODULE_UNLOAD
        /* Reference counts */
        struct module_ref ref[NR_CPUS];
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 0b4cd2fa64aa6cf5a1b6da709b761ab8f2234fc8..70420bbae82b3b219847d0ed5f230728412a1de6 100644 (file)
 struct mtd_info;
 /* Scan and identify a NAND device */
 extern int nand_scan (struct mtd_info *mtd, int max_chips);
+/* Separate phases of nand_scan(), allowing board driver to intervene
+ * and override command or ECC setup according to flash type */
+extern int nand_scan_ident(struct mtd_info *mtd, int max_chips);
+extern int nand_scan_tail(struct mtd_info *mtd);
+
 /* Free resources held by the NAND device */
 extern void nand_release (struct mtd_info *mtd);
 
+/* Internal helper for board drivers which need to override command function */
+extern void nand_wait_ready(struct mtd_info *mtd);
+
 /* The maximum number of NAND chips in an array */
 #define NAND_MAX_CHIPS         8
 
@@ -178,7 +186,9 @@ typedef enum {
 #define NAND_USE_FLASH_BBT     0x00010000
 /* This option skips the bbt scan during initialization. */
 #define NAND_SKIP_BBTSCAN      0x00020000
-
+/* This option is defined if the board driver allocates its own buffers
+   (e.g. because it needs them DMA-coherent */
+#define NAND_OWN_BUFFERS       0x00040000
 /* Options set by nand scan */
 /* Nand scan has allocated controller struct */
 #define NAND_CONTROLLER_ALLOC  0x80000000
@@ -228,6 +238,8 @@ struct nand_hw_control {
  *             be provided if an hardware ECC is available
  * @calculate: function for ecc calculation or readback from ecc hardware
  * @correct:   function for ecc correction, matching to ecc generator (sw/hw)
+ * @read_page_raw:     function to read a raw page without ECC
+ * @write_page_raw:    function to write a raw page without ECC
  * @read_page: function to read a page according to the ecc generator requirements
  * @write_page:        function to write a page according to the ecc generator requirements
  * @read_oob:  function to read chip OOB data
@@ -249,6 +261,12 @@ struct nand_ecc_ctrl {
        int                     (*correct)(struct mtd_info *mtd, uint8_t *dat,
                                           uint8_t *read_ecc,
                                           uint8_t *calc_ecc);
+       int                     (*read_page_raw)(struct mtd_info *mtd,
+                                                struct nand_chip *chip,
+                                                uint8_t *buf);
+       void                    (*write_page_raw)(struct mtd_info *mtd,
+                                                 struct nand_chip *chip,
+                                                 const uint8_t *buf);
        int                     (*read_page)(struct mtd_info *mtd,
                                             struct nand_chip *chip,
                                             uint8_t *buf);
@@ -337,6 +355,7 @@ struct nand_buffers {
  * @priv:              [OPTIONAL] pointer to private chip date
  * @errstat:           [OPTIONAL] hardware specific function to perform additional error status checks
  *                     (determine if errors are correctable)
+ * @write_page         [REPLACEABLE] High-level page write function
  */
 
 struct nand_chip {
@@ -359,6 +378,8 @@ struct nand_chip {
        void            (*erase_cmd)(struct mtd_info *mtd, int page);
        int             (*scan_bbt)(struct mtd_info *mtd);
        int             (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page);
+       int             (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
+                                     const uint8_t *buf, int page, int cached, int raw);
 
        int             chip_delay;
        unsigned int    options;
@@ -380,7 +401,7 @@ struct nand_chip {
        struct nand_ecclayout   *ecclayout;
 
        struct nand_ecc_ctrl ecc;
-       struct nand_buffers buffers;
+       struct nand_buffers *buffers;
        struct nand_hw_control hwcontrol;
 
        struct mtd_oob_ops ops;
index 1f4972155249887c1c70e3a2a25f42520ac2f871..6f045b586e768b16d2d9949828a6d6f2d99f5985 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  linux/include/linux/mtd/onenand.h
  *
- *  Copyright (C) 2005 Samsung Electronics
+ *  Copyright (C) 2005-2006 Samsung Electronics
  *  Kyungmin Park <kyungmin.park@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -96,6 +96,7 @@ struct onenand_chip {
        void __iomem            *base;
        unsigned int            chipsize;
        unsigned int            device_id;
+       unsigned int            version_id;
        unsigned int            density_mask;
        unsigned int            options;
 
@@ -149,7 +150,8 @@ struct onenand_chip {
 /*
  * Options bits
  */
-#define ONENAND_CONT_LOCK              (0x0001)
+#define ONENAND_HAS_CONT_LOCK          (0x0001)
+#define ONENAND_HAS_UNLOCK_ALL         (0x0002)
 #define ONENAND_PAGEBUF_ALLOC          (0x1000)
 
 /*
index 4a72818d25453205f64d7e538913885ebd1c2657..9e409fe6ded6ab76ed7d52507f47870a1bc11bfb 100644 (file)
@@ -3,7 +3,7 @@
  *
  *  OneNAND Register header file
  *
- *  Copyright (C) 2005 Samsung Electronics
+ *  Copyright (C) 2005-2006 Samsung Electronics
  *
  * 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
@@ -72,6 +72,7 @@
 #define ONENAND_DEVICE_VCC_MASK                (0x3)
 
 #define ONENAND_DEVICE_DENSITY_512Mb   (0x002)
+#define ONENAND_DEVICE_DENSITY_1Gb     (0x003)
 
 /*
  * Version ID Register F002h (R)
 #define ONENAND_CMD_UNLOCK             (0x23)
 #define ONENAND_CMD_LOCK               (0x2A)
 #define ONENAND_CMD_LOCK_TIGHT         (0x2C)
+#define ONENAND_CMD_UNLOCK_ALL         (0x27)
 #define ONENAND_CMD_ERASE              (0x94)
 #define ONENAND_CMD_RESET              (0xF0)
 #define ONENAND_CMD_OTP_ACCESS         (0x65)
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 3abc8e3b4879a5eac2dd54374f0fb9b37ca9f3a7..d137009f0b2be0feb70efcffba537f899195865d 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <linux/mount.h>
 #include <linux/sched.h>
+#include <linux/nsproxy.h>
 
 struct namespace {
        atomic_t                count;
@@ -26,11 +27,8 @@ static inline void put_namespace(struct namespace *namespace)
 
 static inline void exit_namespace(struct task_struct *p)
 {
-       struct namespace *namespace = p->namespace;
+       struct namespace *namespace = p->nsproxy->namespace;
        if (namespace) {
-               task_lock(p);
-               p->namespace = NULL;
-               task_unlock(p);
                put_namespace(namespace);
        }
 }
index 110fec6a40a2bfc1f7e17dba9d0cbafa7082759f..6270f6f336936c1097f2d72ef5b45c062b7784ab 100644 (file)
@@ -1,6 +1,18 @@
 #ifndef __LINUX_BRIDGE_EBT_MARK_T_H
 #define __LINUX_BRIDGE_EBT_MARK_T_H
 
+/* The target member is reused for adding new actions, the
+ * value of the real target is -1 to -NUM_STANDARD_TARGETS.
+ * For backward compatibility, the 4 lsb (2 would be enough,
+ * but let's play it safe) are kept to designate this target.
+ * The remaining bits designate the action. By making the set
+ * action 0xfffffff0, the result will look ok for older
+ * versions. [September 2006] */
+#define MARK_SET_VALUE (0xfffffff0)
+#define MARK_OR_VALUE  (0xffffffe0)
+#define MARK_AND_VALUE (0xffffffd0)
+#define MARK_XOR_VALUE (0xffffffc0)
+
 struct ebt_mark_t_info
 {
        unsigned long mark;
index ce02c984f3bae354307b3a398c62c166dcc8d83b..5b63a231a76bb14bad1b17960c6da150bacd9e1b 100644 (file)
@@ -77,7 +77,7 @@ enum nf_ip_hook_priorities {
 #define SO_ORIGINAL_DST 80
 
 #ifdef __KERNEL__
-extern int ip_route_me_harder(struct sk_buff **pskb);
+extern int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type);
 extern int ip_xfrm_me_harder(struct sk_buff **pskb);
 extern unsigned int nf_ip_checksum(struct sk_buff *skb, unsigned int hook,
                                   unsigned int dataoff, u_int8_t protocol);
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 2dcad295fecef2685ffb4121d4ea977cc6b8c279..d0d4aae7085fd5fea09de2831132ee3d0e80b734 100644 (file)
@@ -140,6 +140,12 @@ struct posix_acl *nfsd_get_posix_acl(struct svc_fh *, int);
 int nfsd_set_posix_acl(struct svc_fh *, int, struct posix_acl *);
 #endif
 
+enum vers_op {NFSD_SET, NFSD_CLEAR, NFSD_TEST, NFSD_AVAIL };
+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
@@ -210,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)
@@ -286,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)
@@ -302,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 31a3cb617ce0b02c1129bcba8d58ff1c4bac000a..069257ea99a0fe4c92de7ccc4a993d88b35774ea 100644 (file)
@@ -290,8 +290,9 @@ fill_post_wcc(struct svc_fh *fhp)
  * vfs.c:nfsd_rename as it needs to grab 2 i_mutex's at once
  * so, any changes here should be reflected there.
  */
+
 static inline void
-fh_lock(struct svc_fh *fhp)
+fh_lock_nested(struct svc_fh *fhp, unsigned int subclass)
 {
        struct dentry   *dentry = fhp->fh_dentry;
        struct inode    *inode;
@@ -310,11 +311,17 @@ fh_lock(struct svc_fh *fhp)
        }
 
        inode = dentry->d_inode;
-       mutex_lock(&inode->i_mutex);
+       mutex_lock_nested(&inode->i_mutex, subclass);
        fill_pre_wcc(fhp);
        fhp->fh_locked = 1;
 }
 
+static inline void
+fh_lock(struct svc_fh *fhp)
+{
+       fh_lock_nested(fhp, I_MUTEX_NORMAL);
+}
+
 /*
  * Unlock a file handle/inode
  */
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 dae0faea28070a594c49d886458e1ebc4934a477..8bcddccb6c427e81a7a7b960d1f25afaa1bb9b6f 100644 (file)
 #define NFSCTL_GETFD           7       /* get an fh by path (used by mountd) */
 #define        NFSCTL_GETFS            8       /* get an fh by path with max FH len */
 
-/*
- * Macros used to set version
- */
-#define NFSCTL_VERSET(_cltbits, _v)   ((_cltbits) |=  (1 << (_v)))
-#define NFSCTL_VERUNSET(_cltbits, _v) ((_cltbits) &= ~(1 << (_v)))
-#define NFSCTL_VERISSET(_cltbits, _v) ((_cltbits) & (1 << (_v)))
-
-#if defined(CONFIG_NFSD_V4)
-#define        NFSCTL_VERALL   (0x1c /* 0b011100 */)
-#elif defined(CONFIG_NFSD_V3)
-#define        NFSCTL_VERALL   (0x0c /* 0b001100 */)
-#else
-#define        NFSCTL_VERALL   (0x04 /* 0b000100 */)
-#endif
-
 /* SVC */
 struct nfsctl_svc {
        unsigned short          svc_port;
@@ -134,8 +119,6 @@ extern int          exp_delclient(struct nfsctl_client *ncp);
 extern int             exp_export(struct nfsctl_export *nxp);
 extern int             exp_unexport(struct nfsctl_export *nxp);
 
-extern unsigned int nfsd_versbits;
-
 #endif /* __KERNEL__ */
 
 #endif /* NFSD_SYSCALL_H */
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 1a9ef3e627d1b6e04984688c071ed6e27fa964fd..5dce5c21822ca12bc6b3c6423352b50fcbe75b44 100644 (file)
@@ -352,6 +352,7 @@ extern nodemask_t node_possible_map;
 #define node_possible(node)    node_isset((node), node_possible_map)
 #define first_online_node      first_node(node_online_map)
 #define next_online_node(nid)  next_node((nid), node_online_map)
+int highest_possible_node_id(void);
 #else
 #define num_online_nodes()     1
 #define num_possible_nodes()   1
@@ -359,6 +360,7 @@ extern nodemask_t node_possible_map;
 #define node_possible(node)    ((node) == 0)
 #define first_online_node      0
 #define next_online_node(nid)  (MAX_NUMNODES)
+#define highest_possible_node_id()     0
 #endif
 
 #define any_online_node(mask)                  \
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 */
diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h
new file mode 100644 (file)
index 0000000..f6baecd
--- /dev/null
@@ -0,0 +1,52 @@
+#ifndef _LINUX_NSPROXY_H
+#define _LINUX_NSPROXY_H
+
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+
+struct namespace;
+struct uts_namespace;
+struct ipc_namespace;
+
+/*
+ * A structure to contain pointers to all per-process
+ * namespaces - fs (mount), uts, network, sysvipc, etc.
+ *
+ * 'count' is the number of tasks holding a reference.
+ * The count for each namespace, then, will be the number
+ * of nsproxies pointing to it, not the number of tasks.
+ *
+ * The nsproxy is shared by tasks which share all namespaces.
+ * As soon as a single namespace is cloned or unshared, the
+ * nsproxy is copied.
+ */
+struct nsproxy {
+       atomic_t count;
+       spinlock_t nslock;
+       struct uts_namespace *uts_ns;
+       struct ipc_namespace *ipc_ns;
+       struct namespace *namespace;
+};
+extern struct nsproxy init_nsproxy;
+
+struct nsproxy *dup_namespaces(struct nsproxy *orig);
+int copy_namespaces(int flags, struct task_struct *tsk);
+void get_task_namespaces(struct task_struct *tsk);
+void free_nsproxy(struct nsproxy *ns);
+
+static inline void put_nsproxy(struct nsproxy *ns)
+{
+       if (atomic_dec_and_test(&ns->count)) {
+               free_nsproxy(ns);
+       }
+}
+
+static inline void exit_task_namespaces(struct task_struct *p)
+{
+       struct nsproxy *ns = p->nsproxy;
+       if (ns) {
+               put_nsproxy(ns);
+               p->nsproxy = NULL;
+       }
+}
+#endif
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 c9ffbc3843d57894d44474bf841664203d60091a..f069df2454699b408fa311d619cd9d3f780663da 100644 (file)
 #define PCI_VENDOR_ID_ROCKWELL         0x127A
 
 #define PCI_VENDOR_ID_ITE              0x1283
-#define PCI_DEVICE_ID_ITE_IT8172G      0x8172
-#define PCI_DEVICE_ID_ITE_IT8172G_AUDIO 0x0801
 #define PCI_DEVICE_ID_ITE_8211         0x8211
 #define PCI_DEVICE_ID_ITE_8212         0x8212
 #define PCI_DEVICE_ID_ITE_8872         0x8872
 #define PCI_DEVICE_ID_PANACOM_QUADMODEM        0x0400
 #define PCI_DEVICE_ID_PANACOM_DUALMODEM        0x0402
 
+#define PCI_VENDOR_ID_SIPACKETS                0x14d9
+#define PCI_DEVICE_ID_SP1011           0x0010
 
 #define PCI_VENDOR_ID_AFAVLAB          0x14db
 #define PCI_DEVICE_ID_AFAVLAB_P028     0x2180
 #define PCI_DEVICE_ID_FARSITE_TE1C      0x1612
 
 #define PCI_VENDOR_ID_SIBYTE           0x166d
+#define PCI_DEVICE_ID_BCM1250_PCI      0x0001
 #define PCI_DEVICE_ID_BCM1250_HT       0x0002
 
 #define PCI_VENDOR_ID_NETCELL          0x169c
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 93da7e2d9f30bdda2268d8163e3c9f29d73a4a4a..2c0007d172189390911779471f54db752e3dd50d 100644 (file)
@@ -68,6 +68,8 @@ extern struct task_struct *FASTCALL(pid_task(struct pid *pid, enum pid_type));
 extern struct task_struct *FASTCALL(get_pid_task(struct pid *pid,
                                                enum pid_type));
 
+extern struct pid *get_task_pid(struct task_struct *task, enum pid_type type);
+
 /*
  * attach_pid() and detach_pid() must be called with the tasklist_lock
  * write-held.
@@ -89,33 +91,42 @@ extern struct pid *FASTCALL(find_pid(int nr));
  * Lookup a PID in the hash table, and return with it's count elevated.
  */
 extern struct pid *find_get_pid(int nr);
+extern struct pid *find_ge_pid(int nr);
 
 extern struct pid *alloc_pid(void);
 extern void FASTCALL(free_pid(struct pid *pid));
 
-#define pid_next(task, type)                                   \
-       ((task)->pids[(type)].node.next)
-
-#define pid_next_task(task, type)                              \
-       hlist_entry(pid_next(task, type), struct task_struct,   \
-                       pids[(type)].node)
+static inline pid_t pid_nr(struct pid *pid)
+{
+       pid_t nr = 0;
+       if (pid)
+               nr = pid->nr;
+       return nr;
+}
 
 
-/* We could use hlist_for_each_entry_rcu here but it takes more arguments
- * than the do_each_task_pid/while_each_task_pid.  So we roll our own
- * to preserve the existing interface.
- */
 #define do_each_task_pid(who, type, task)                              \
-       if ((task = find_task_by_pid_type(type, who))) {                \
-               prefetch(pid_next(task, type));                         \
-               do {
+       do {                                                            \
+               struct hlist_node *pos___;                              \
+               struct pid *pid___ = find_pid(who);                     \
+               if (pid___ != NULL)                                     \
+                       hlist_for_each_entry_rcu((task), pos___,        \
+                               &pid___->tasks[type], pids[type].node) {
 
 #define while_each_task_pid(who, type, task)                           \
-               } while (pid_next(task, type) &&  ({                    \
-                               task = pid_next_task(task, type);       \
-                               rcu_dereference(task);                  \
-                               prefetch(pid_next(task, type));         \
-                               1; }) );                                \
-       }
+                       }                                               \
+       } while (0)
+
+
+#define do_each_pid_task(pid, type, task)                              \
+       do {                                                            \
+               struct hlist_node *pos___;                              \
+               if (pid != NULL)                                        \
+                       hlist_for_each_entry_rcu((task), pos___,        \
+                               &pid->tasks[type], pids[type].node) {
+
+#define while_each_pid_task(pid, type, task)                           \
+                       }                                               \
+       } while (0)
 
 #endif /* _LINUX_PID_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 57f70bc8b24bba1bf3f9e9336a1a10b01945778c..87dec8fe6de900da1c495175144e21f99a1bf6b1 100644 (file)
@@ -244,13 +244,15 @@ static inline void kclist_add(struct kcore_list *new, void *addr, size_t size)
 extern void kclist_add(struct kcore_list *, void *, size_t);
 #endif
 
+union proc_op {
+       int (*proc_get_link)(struct inode *, struct dentry **, struct vfsmount **);
+       int (*proc_read)(struct task_struct *task, char *page);
+};
+
 struct proc_inode {
        struct pid *pid;
        int fd;
-       union {
-               int (*proc_get_link)(struct inode *, struct dentry **, struct vfsmount **);
-               int (*proc_read)(struct task_struct *task, char *page);
-       } op;
+       union proc_op op;
        struct proc_dir_entry *pde;
        struct inode vfs_inode;
 };
diff --git a/include/linux/pspace.h b/include/linux/pspace.h
new file mode 100644 (file)
index 0000000..91d48b8
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef _LINUX_PSPACE_H
+#define _LINUX_PSPACE_H
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/threads.h>
+#include <linux/pid.h>
+
+struct pidmap {
+       atomic_t nr_free;
+       void *page;
+};
+
+#define PIDMAP_ENTRIES         ((PID_MAX_LIMIT + 8*PAGE_SIZE - 1)/PAGE_SIZE/8)
+
+struct pspace {
+       struct pidmap pidmap[PIDMAP_ENTRIES];
+       int last_pid;
+};
+
+extern struct pspace init_pspace;
+
+#endif /* _LINUX_PSPACE_H */
index 63df898fe2e95dcf092a3ac5dedeb76b431f8122..84d88775185556e4d2a8a6b0560bcfc9c202038a 100644 (file)
@@ -265,6 +265,8 @@ int bitmap_update_sb(struct bitmap *bitmap);
 int  bitmap_setallbits(struct bitmap *bitmap);
 void bitmap_write_all(struct bitmap *bitmap);
 
+void bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e);
+
 /* these are exported */
 int bitmap_startwrite(struct bitmap *bitmap, sector_t offset,
                        unsigned long sectors, int behind);
index c588709acbbc90b868681dda826605fa14afb0a5..866a1e2b0ce049fd991f3e85d52bdeea3b82d520 100644 (file)
@@ -95,7 +95,6 @@ extern int sync_page_io(struct block_device *bdev, sector_t sector, int size,
 extern void md_do_sync(mddev_t *mddev);
 extern void md_new_event(mddev_t *mddev);
 
-extern void md_update_sb(mddev_t * mddev);
 
 #endif /* CONFIG_MD */
 #endif 
index 920b94fe31fa2ed5184f8cdb4d41683efeeb15f4..8245c282168b4a436884653c61eda6a1490d83eb 100644 (file)
 #define        LEVEL_NONE              (-1000000)
 
 #define MaxSector (~(sector_t)0)
-#define MD_THREAD_NAME_MAX 14
 
 typedef struct mddev_s mddev_t;
 typedef struct mdk_rdev_s mdk_rdev_t;
 
-#define MAX_MD_DEVS  256       /* Max number of md dev */
-
 /*
  * options passed in raidrun:
  */
 
-/* Currently this must fix in an 'int' */
+/* Currently this must fit in an 'int' */
 #define MAX_CHUNK_SIZE (1<<30)
 
 /*
@@ -116,7 +113,11 @@ struct mddev_s
        dev_t                           unit;
        int                             md_minor;
        struct list_head                disks;
-       int                             sb_dirty;
+       unsigned long                   flags;
+#define MD_CHANGE_DEVS 0       /* Some device status has changed */
+#define MD_CHANGE_CLEAN 1      /* transition to or from 'clean' */
+#define MD_CHANGE_PENDING 2    /* superblock update in progress */
+
        int                             ro;
 
        struct gendisk                  *gendisk;
index 81da20ccec4dadeab0dd13da2ac94b7e7f48243e..7192035fc4b0680094f3c4f0c2780a79c20dfd1b 100644 (file)
@@ -41,7 +41,7 @@
 
 /* usage */
 #define RUN_ARRAY              _IOW (MD_MAJOR, 0x30, mdu_param_t)
-#define START_ARRAY            _IO (MD_MAJOR, 0x31)
+/*  0x31 was START_ARRAY  */
 #define STOP_ARRAY             _IO (MD_MAJOR, 0x32)
 #define STOP_ARRAY_RO          _IO (MD_MAJOR, 0x33)
 #define RESTART_ARRAY_RW       _IO (MD_MAJOR, 0x34)
index 3009c813d83d33d2748804d4db1081bce811cb5f..0a9ba7c3302e2393e881244983a3397807e29dfb 100644 (file)
@@ -30,7 +30,6 @@ struct r1_private_data_s {
        mddev_t                 *mddev;
        mirror_info_t           *mirrors;
        int                     raid_disks;
-       int                     working_disks;
        int                     last_used;
        sector_t                next_seq_sect;
        spinlock_t              device_lock;
index c41e56a7c090801f401f97e116986204a5fb728d..e9091cfeb286c2a9b0d30dc57e6748933bb3a9ee 100644 (file)
@@ -16,7 +16,6 @@ struct r10_private_data_s {
        mddev_t                 *mddev;
        mirror_info_t           *mirrors;
        int                     raid_disks;
-       int                     working_disks;
        spinlock_t              device_lock;
 
        /* geometry */
index 20ed4c997636fac9b92aa003a982c5c641d1a45d..f13299a15591ed6170bb440495b69edd6262104a 100644 (file)
@@ -195,8 +195,9 @@ struct stripe_head {
  * it to the count of prereading stripes.
  * When write is initiated, or the stripe refcnt == 0 (just in case) we
  * clear the PREREAD_ACTIVE flag and decrement the count
- * Whenever the delayed queue is empty and the device is not plugged, we
- * move any strips from delayed to handle and clear the DELAYED flag and set PREREAD_ACTIVE.
+ * Whenever the 'handle' queue is empty and the device is not plugged, we
+ * move any strips from delayed to handle and clear the DELAYED flag and set
+ * PREREAD_ACTIVE.
  * In stripe_handle, if we find pre-reading is necessary, we do it if
  * PREREAD_ACTIVE is set, else we set DELAYED which will send it to the delayed queue.
  * HANDLE gets cleared if stripe_handle leave nothing locked.
@@ -213,7 +214,7 @@ struct raid5_private_data {
        struct disk_info        *spare;
        int                     chunk_size, level, algorithm;
        int                     max_degraded;
-       int                     raid_disks, working_disks, failed_disks;
+       int                     raid_disks;
        int                     max_nr_stripes;
 
        /* used during an expand */
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 7ef899c47c29296b14f28030cab737fc6dc30700..331f4502e92bb6540f407d2c1d735c693a28edd9 100644 (file)
@@ -24,6 +24,8 @@
 #define CLONE_UNTRACED         0x00800000      /* set if the tracing process can't force CLONE_PTRACE on this clone */
 #define CLONE_CHILD_SETTID     0x01000000      /* set the TID in the child */
 #define CLONE_STOPPED          0x02000000      /* Start in stopped state */
+#define CLONE_NEWUTS           0x04000000      /* New utsname group? */
+#define CLONE_NEWIPC           0x08000000      /* New ipcs */
 
 /*
  * Scheduling policies
@@ -118,7 +120,6 @@ extern unsigned long avenrun[];             /* Load averages */
 
 extern unsigned long total_forks;
 extern int nr_threads;
-extern int last_pid;
 DECLARE_PER_CPU(unsigned long, process_counts);
 extern int nr_processes(void);
 extern unsigned long nr_running(void);
@@ -239,7 +240,7 @@ extern signed long schedule_timeout_interruptible(signed long timeout);
 extern signed long schedule_timeout_uninterruptible(signed long timeout);
 asmlinkage void schedule(void);
 
-struct namespace;
+struct nsproxy;
 
 /* Maximum number of active map areas.. This is a random (large) number */
 #define DEFAULT_MAX_MAP_COUNT  65536
@@ -624,9 +625,17 @@ enum idle_type
 #define SD_WAKE_BALANCE                64      /* Perform balancing at task wakeup */
 #define SD_SHARE_CPUPOWER      128     /* Domain members share cpu power */
 #define SD_POWERSAVINGS_BALANCE        256     /* Balance for power savings */
+#define SD_SHARE_PKG_RESOURCES 512     /* Domain members share cpu pkg resources */
 
-#define BALANCE_FOR_POWER      ((sched_mc_power_savings || sched_smt_power_savings) \
-                                ? SD_POWERSAVINGS_BALANCE : 0)
+#define BALANCE_FOR_MC_POWER   \
+       (sched_smt_power_savings ? SD_POWERSAVINGS_BALANCE : 0)
+
+#define BALANCE_FOR_PKG_POWER  \
+       ((sched_mc_power_savings || sched_smt_power_savings) ?  \
+        SD_POWERSAVINGS_BALANCE : 0)
+
+#define test_sd_parent(sd, flag)       ((sd->parent &&         \
+                                        (sd->parent->flags & flag)) ? 1 : 0)
 
 
 struct sched_group {
@@ -643,6 +652,7 @@ struct sched_group {
 struct sched_domain {
        /* These fields must be setup */
        struct sched_domain *parent;    /* top domain must be null terminated */
+       struct sched_domain *child;     /* bottom domain must be null terminated */
        struct sched_group *groups;     /* the balancing groups of the domain */
        cpumask_t span;                 /* span of all CPUs in this domain */
        unsigned long min_interval;     /* Minimum balance interval ms */
@@ -754,6 +764,7 @@ static inline void prefetch_stack(struct task_struct *t) { }
 struct audit_context;          /* See audit.c */
 struct mempolicy;
 struct pipe_inode_info;
+struct uts_namespace;
 
 enum sleep_type {
        SLEEP_NORMAL,
@@ -897,8 +908,8 @@ struct task_struct {
        struct fs_struct *fs;
 /* open file information */
        struct files_struct *files;
-/* namespace */
-       struct namespace *namespace;
+/* namespaces */
+       struct nsproxy *nsproxy;
 /* signal handlers */
        struct signal_struct *signal;
        struct sighand_struct *sighand;
@@ -1020,6 +1031,26 @@ static inline pid_t process_group(struct task_struct *tsk)
        return tsk->signal->pgrp;
 }
 
+static inline struct pid *task_pid(struct task_struct *task)
+{
+       return task->pids[PIDTYPE_PID].pid;
+}
+
+static inline struct pid *task_tgid(struct task_struct *task)
+{
+       return task->group_leader->pids[PIDTYPE_PID].pid;
+}
+
+static inline struct pid *task_pgrp(struct task_struct *task)
+{
+       return task->group_leader->pids[PIDTYPE_PGID].pid;
+}
+
+static inline struct pid *task_session(struct task_struct *task)
+{
+       return task->group_leader->pids[PIDTYPE_SID].pid;
+}
+
 /**
  * pid_alive - check that a task structure is not stale
  * @p: Task structure to be checked.
@@ -1043,6 +1074,8 @@ static inline int is_init(struct task_struct *tsk)
        return tsk->pid == 1;
 }
 
+extern struct pid *cad_pid;
+
 extern void free_task(struct task_struct *tsk);
 #define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0)
 
@@ -1247,10 +1280,15 @@ extern int send_sig_info(int, struct siginfo *, struct task_struct *);
 extern int send_group_sig_info(int, struct siginfo *, struct task_struct *);
 extern int force_sigsegv(int, struct task_struct *);
 extern int force_sig_info(int, struct siginfo *, struct task_struct *);
+extern int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp);
+extern int kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp);
+extern int kill_pid_info(int sig, struct siginfo *info, struct pid *pid);
+extern int kill_pid_info_as_uid(int, struct siginfo *, struct pid *, uid_t, uid_t, u32);
+extern int kill_pgrp(struct pid *pid, int sig, int priv);
+extern int kill_pid(struct pid *pid, int sig, int priv);
 extern int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp);
 extern int kill_pg_info(int, struct siginfo *, pid_t);
 extern int kill_proc_info(int, struct siginfo *, pid_t);
-extern int kill_proc_info_as_uid(int, struct siginfo *, pid_t, uid_t, uid_t, u32);
 extern void do_notify_parent(struct task_struct *, int);
 extern void force_sig(int, struct task_struct *);
 extern void force_sig_specific(int, struct task_struct *);
@@ -1265,6 +1303,11 @@ extern int send_group_sigqueue(int, struct sigqueue *,  struct task_struct *);
 extern int do_sigaction(int, struct k_sigaction *, struct k_sigaction *);
 extern int do_sigaltstack(const stack_t __user *, stack_t __user *, unsigned long);
 
+static inline int kill_cad_pid(int sig, int priv)
+{
+       return kill_pid(cad_pid, sig, priv);
+}
+
 /* These can be the second arg to send_sig_info/send_group_sig_info.  */
 #define SEND_SIG_NOINFO ((struct siginfo *) 0)
 #define SEND_SIG_PRIV  ((struct siginfo *) 1)
@@ -1358,6 +1401,17 @@ extern void wait_task_inactive(struct task_struct * p);
 /* de_thread depends on thread_group_leader not being a pid based check */
 #define thread_group_leader(p) (p == p->group_leader)
 
+/* Do to the insanities of de_thread it is possible for a process
+ * to have the pid of the thread group leader without actually being
+ * the thread group leader.  For iteration through the pids in proc
+ * all we care about is that we have a task with the appropriate
+ * pid, we don't actually care if we have the right task.
+ */
+static inline int has_group_leader_pid(struct task_struct *p)
+{
+       return p->pid == p->tgid;
+}
+
 static inline struct task_struct *next_thread(const struct task_struct *p)
 {
        return list_entry(rcu_dereference(p->thread_group.next),
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 86501a3de2ac1d771c9b32958ca5b3fdf8a99dee..de2e68159d96e885eef6aea5996bb25f6e1eb25e 100644 (file)
@@ -319,6 +319,7 @@ struct uart_info {
 #define UIF_CTS_FLOW           ((__force uif_t) (1 << 26))
 #define UIF_NORMAL_ACTIVE      ((__force uif_t) (1 << 29))
 #define UIF_INITIALIZED                ((__force uif_t) (1 << 31))
+#define UIF_SUSPENDED          ((__force uif_t) (1 << 30))
 
        int                     blocked_open;
 
@@ -414,7 +415,7 @@ uart_handle_sysrq_char(struct uart_port *port, unsigned int ch,
 #ifdef SUPPORT_SYSRQ
        if (port->sysrq) {
                if (ch && time_before(jiffies, port->sysrq)) {
-                       handle_sysrq(ch, regs, NULL);
+                       handle_sysrq(ch, regs, port->info->tty);
                        port->sysrq = 0;
                        return 1;
                }
index 6348e8330897c3393a88e937ef7ae167c767faca..c9069310b6acc531242a64210743b471639fea77 100644 (file)
@@ -217,5 +217,8 @@ static inline void serio_unpin_driver(struct serio *serio)
 #define SERIO_LKKBD    0x28
 #define SERIO_ELO      0x29
 #define SERIO_MICROTOUCH       0x30
+#define SERIO_PENMOUNT 0x31
+#define SERIO_TOUCHRIGHT       0x32
+#define SERIO_TOUCHWIN 0x33
 
 #endif
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 8669291352dba326e952d0f2a02e5e2a552101b8..679ef0d70b6b1bae44fb4d9a60af100b1ec2d8fb 100644 (file)
@@ -57,7 +57,7 @@
 #include <linux/time.h>
 
 struct kstat {
-       unsigned long   ino;
+       u64             ino;
        dev_t           dev;
        umode_t         mode;
        unsigned int    nlink;
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 73140ee5c638ab631916ecf6fb697da58384693d..d6288e89fd9d64308113cc0035afd29ea1f71528 100644 (file)
 #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>
 
+/*
+ * This is the RPC server thread function prototype
+ */
+typedef void           (*svc_thread_fn)(struct svc_rqst *);
+
+/*
+ *
+ * RPC service thread pool.
+ *
+ * Pool of threads and temporary sockets.  Generally there is only
+ * a single one of these per RPC service, but on NUMA machines those
+ * services that can benefit from it (i.e. nfs but not lockd) will
+ * have one pool per NUMA node.  This optimisation reduces cross-
+ * node traffic on multi-node NUMA NFS servers.
+ */
+struct svc_pool {
+       unsigned int            sp_id;          /* pool id; also node id on NUMA */
+       spinlock_t              sp_lock;        /* protects all fields */
+       struct list_head        sp_threads;     /* idle server threads */
+       struct list_head        sp_sockets;     /* pending sockets */
+       unsigned int            sp_nrthreads;   /* # of threads in pool */
+       struct list_head        sp_all_threads; /* all server threads */
+} ____cacheline_aligned_in_smp;
+
 /*
  * RPC service.
  *
@@ -28,8 +53,6 @@
  * We currently do not support more than one RPC program per daemon.
  */
 struct svc_serv {
-       struct list_head        sv_threads;     /* idle server threads */
-       struct list_head        sv_sockets;     /* pending sockets */
        struct svc_program *    sv_program;     /* RPC program */
        struct svc_stat *       sv_stats;       /* RPC statistics */
        spinlock_t              sv_lock;
@@ -40,16 +63,61 @@ struct svc_serv {
        struct list_head        sv_permsocks;   /* all permanent sockets */
        struct list_head        sv_tempsocks;   /* all temporary sockets */
        int                     sv_tmpcnt;      /* count of temporary sockets */
+       struct timer_list       sv_temptimer;   /* timer for aging temporary sockets */
 
        char *                  sv_name;        /* service name */
+
+       unsigned int            sv_nrpools;     /* number of thread pools */
+       struct svc_pool *       sv_pools;       /* array of thread pools */
+
+       void                    (*sv_shutdown)(struct svc_serv *serv);
+                                               /* Callback to use when last thread
+                                                * exits.
+                                                */
+
+       struct module *         sv_module;      /* optional module to count when
+                                                * adding threads */
+       svc_thread_fn           sv_function;    /* main function for threads */
+       int                     sv_kill_signal; /* signal to kill threads */
 };
 
+/*
+ * We use sv_nrthreads as a reference count.  svc_destroy() drops
+ * this refcount, so we need to bump it up around operations that
+ * change the number of threads.  Horrible, but there it is.
+ * Should be called with the BKL held.
+ */
+static inline void svc_get(struct svc_serv *serv)
+{
+       serv->sv_nrthreads++;
+}
+
 /*
  * 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.
@@ -123,15 +191,16 @@ 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 */
+       struct list_head        rq_all;         /* all threads list */
        struct svc_sock *       rq_sock;        /* socket */
        struct sockaddr_in      rq_addr;        /* peer address */
        int                     rq_addrlen;
 
        struct svc_serv *       rq_server;      /* RPC service definition */
+       struct svc_pool *       rq_pool;        /* thread pool */
        struct svc_procedure *  rq_procinfo;    /* procedure info */
        struct auth_ops *       rq_authop;      /* authentication flavour */
        struct svc_cred         rq_cred;        /* auth info */
@@ -140,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 */
@@ -180,6 +248,7 @@ struct svc_rqst {
                                                 * to prevent encrypting page
                                                 * cache pages */
        wait_queue_head_t       rq_wait;        /* synchronization */
+       struct task_struct      *rq_task;       /* service thread */
 };
 
 /*
@@ -205,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;
@@ -297,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.
@@ -320,21 +347,22 @@ struct svc_procedure {
        unsigned int            pc_xdrressize;  /* maximum size of XDR reply */
 };
 
-/*
- * This is the RPC server thread function prototype
- */
-typedef void           (*svc_thread_fn)(struct svc_rqst *);
-
 /*
  * Function prototypes.
  */
-struct svc_serv *  svc_create(struct svc_program *, unsigned int);
+struct svc_serv *  svc_create(struct svc_program *, unsigned int,
+                             void (*shutdown)(struct svc_serv*));
 int               svc_create_thread(svc_thread_fn, struct svc_serv *);
 void              svc_exit_thread(struct svc_rqst *);
+struct svc_serv *  svc_create_pooled(struct svc_program *, unsigned int,
+                       void (*shutdown)(struct svc_serv*),
+                       svc_thread_fn, int sig, struct module *);
+int               svc_set_num_threads(struct svc_serv *, struct svc_pool *, int);
 void              svc_destroy(struct svc_serv *);
-int               svc_process(struct svc_serv *, struct svc_rqst *);
+int               svc_process(struct svc_rqst *);
 int               svc_register(struct svc_serv *, int, unsigned short);
 void              svc_wake_up(struct svc_serv *);
 void              svc_reserve(struct svc_rqst *rqstp, int space);
+struct svc_pool *  svc_pool_for_cpu(struct svc_serv *serv, int cpu);
 
 #endif /* SUNRPC_SVC_H */
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 b4acb3d37c3f2556e2b5f01efe587c94c6b8cced..98b21ad370fdd529c7a35105642276876360ff82 100644 (file)
@@ -20,8 +20,9 @@ struct svc_sock {
        struct socket *         sk_sock;        /* berkeley socket layer */
        struct sock *           sk_sk;          /* INET layer */
 
+       struct svc_pool *       sk_pool;        /* current pool iff queued */
        struct svc_serv *       sk_server;      /* service for this socket */
-       unsigned int            sk_inuse;       /* use count */
+       atomic_t                sk_inuse;       /* use count */
        unsigned long           sk_flags;
 #define        SK_BUSY         0                       /* enqueued/receiving */
 #define        SK_CONN         1                       /* conn pending */
@@ -31,9 +32,12 @@ struct svc_sock {
 #define        SK_DEAD         6                       /* socket closed */
 #define        SK_CHNGBUF      7                       /* need to change snd/rcv buffer sizes */
 #define        SK_DEFERRED     8                       /* request on sk_deferred */
+#define        SK_OLD          9                       /* used for temp socket aging mark+sweep */
+#define        SK_DETACHED     10                      /* detached from tempsocks list */
 
-       int                     sk_reserved;    /* space on outq that is reserved */
+       atomic_t                sk_reserved;    /* space on outq that is reserved */
 
+       spinlock_t              sk_defer_lock;  /* protects sk_deferred */
        struct list_head        sk_deferred;    /* deferred requests that need to
                                                 * be revisted */
        struct mutex            sk_mutex;       /* to serialize sending data */
@@ -50,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;
 };
 
 /*
@@ -57,9 +64,14 @@ struct svc_sock {
  */
 int            svc_makesock(struct svc_serv *, int, unsigned short);
 void           svc_delete_socket(struct svc_sock *);
-int            svc_recv(struct svc_serv *, struct svc_rqst *, long);
+int            svc_recv(struct svc_rqst *, long);
 int            svc_send(struct svc_rqst *);
 void           svc_drop(struct svc_rqst *);
 void           svc_sock_update_bufs(struct svc_serv *serv);
+int            svc_sock_names(char *buf, struct svc_serv *serv, char *toclose);
+int            svc_addsock(struct svc_serv *serv,
+                           int fd,
+                           char *name_return,
+                           int *proto);
 
 #endif /* SUNRPC_SVCSOCK_H */
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
  */
index 2d1c3d5c83acc150d9838c881d4d22d79509fc4b..3efcfc7e9c6c705a7e9c42f93c1ed0369fddb3cf 100644 (file)
@@ -599,4 +599,6 @@ asmlinkage long sys_set_robust_list(struct robust_list_head __user *head,
                                    size_t len);
 asmlinkage long sys_getcpu(unsigned __user *cpu, unsigned __user *node, struct getcpu_cache __user *cache);
 
+int kernel_execve(const char *filename, char *const argv[], char *const envp[]);
+
 #endif
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 ec1eca85290ade96c5f42da4d74acac2a8ae2407..da508d1998e413714ee788a4602d2a6478dba96d 100644 (file)
@@ -89,6 +89,7 @@
 #define SD_SIBLING_INIT (struct sched_domain) {                \
        .span                   = CPU_MASK_NONE,        \
        .parent                 = NULL,                 \
+       .child                  = NULL,                 \
        .groups                 = NULL,                 \
        .min_interval           = 1,                    \
        .max_interval           = 2,                    \
 #endif
 #endif /* CONFIG_SCHED_SMT */
 
+#ifdef CONFIG_SCHED_MC
+/* Common values for MC siblings. for now mostly derived from SD_CPU_INIT */
+#ifndef SD_MC_INIT
+#define SD_MC_INIT (struct sched_domain) {             \
+       .span                   = CPU_MASK_NONE,        \
+       .parent                 = NULL,                 \
+       .child                  = NULL,                 \
+       .groups                 = NULL,                 \
+       .min_interval           = 1,                    \
+       .max_interval           = 4,                    \
+       .busy_factor            = 64,                   \
+       .imbalance_pct          = 125,                  \
+       .cache_nice_tries       = 1,                    \
+       .per_cpu_gain           = 100,                  \
+       .busy_idx               = 2,                    \
+       .idle_idx               = 1,                    \
+       .newidle_idx            = 2,                    \
+       .wake_idx               = 1,                    \
+       .forkexec_idx           = 1,                    \
+       .flags                  = SD_LOAD_BALANCE       \
+                               | SD_BALANCE_NEWIDLE    \
+                               | SD_BALANCE_EXEC       \
+                               | SD_WAKE_AFFINE        \
+                               | SD_SHARE_PKG_RESOURCES\
+                               | BALANCE_FOR_MC_POWER, \
+       .last_balance           = jiffies,              \
+       .balance_interval       = 1,                    \
+       .nr_balance_failed      = 0,                    \
+}
+#endif
+#endif /* CONFIG_SCHED_MC */
+
 /* Common values for CPUs */
 #ifndef SD_CPU_INIT
 #define SD_CPU_INIT (struct sched_domain) {            \
        .span                   = CPU_MASK_NONE,        \
        .parent                 = NULL,                 \
+       .child                  = NULL,                 \
        .groups                 = NULL,                 \
        .min_interval           = 1,                    \
        .max_interval           = 4,                    \
                                | SD_BALANCE_NEWIDLE    \
                                | SD_BALANCE_EXEC       \
                                | SD_WAKE_AFFINE        \
-                               | BALANCE_FOR_POWER,    \
+                               | BALANCE_FOR_PKG_POWER,\
        .last_balance           = jiffies,              \
        .balance_interval       = 1,                    \
        .nr_balance_failed      = 0,                    \
 #define SD_ALLNODES_INIT (struct sched_domain) {       \
        .span                   = CPU_MASK_NONE,        \
        .parent                 = NULL,                 \
+       .child                  = NULL,                 \
        .groups                 = NULL,                 \
        .min_interval           = 64,                   \
        .max_interval           = 64*num_online_cpus(), \
        .nr_balance_failed      = 0,                    \
 }
 
-#ifdef CONFIG_SCHED_MC
-#ifndef SD_MC_INIT
-/* for now its same as SD_CPU_INIT.
- * TBD: Tune Domain parameters!
- */
-#define SD_MC_INIT   SD_CPU_INIT
-#endif
-#endif
-
 #ifdef CONFIG_NUMA
 #ifndef SD_NODE_INIT
 #error Please define an appropriate SD_NODE_INIT in include/asm/topology.h!!!
index 58c961c9e1707027fe8989bfa821c78121fdb183..5c8473bb6882e7cc4f7dfe03a33072e94f6bceb2 100644 (file)
@@ -219,7 +219,8 @@ extern struct list_head tty_drivers;
 
 struct tty_driver *alloc_tty_driver(int lines);
 void put_tty_driver(struct tty_driver *driver);
-void tty_set_operations(struct tty_driver *driver, struct tty_operations *op);
+void tty_set_operations(struct tty_driver *driver,
+                       const struct tty_operations *op);
 
 /* tty driver magic number */
 #define TTY_DRIVER_MAGIC               0x5402
index 7168302f98441ea9da3c42c931ea40a23bfec5b1..1fd61eeed664c6958e4595aa455f4c3228807712 100644 (file)
  * Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
  *
  * Changes/Revisions:
+ *     0.3     24/05/2006 (Anssi Hannula <anssi.hannulagmail.com>)
+ *             - update ff support for the changes in kernel interface
+ *             - add UINPUT_VERSION
  *     0.2     16/10/2004 (Micah Dowty <micah@navi.cx>)
  *             - added force feedback support
  *             - added UI_SET_PHYS
  *     0.1     20/06/2002
  *             - first public version
  */
+
+#define UINPUT_VERSION         3
+
 #ifdef __KERNEL__
 #define UINPUT_MINOR           223
 #define UINPUT_NAME            "uinput"
@@ -45,7 +51,10 @@ struct uinput_request {
 
        union {
                int             effect_id;
-               struct ff_effect* effect;
+               struct {
+                       struct ff_effect *effect;
+                       struct ff_effect *old;
+               } upload;
        } u;
 };
 
@@ -58,6 +67,7 @@ struct uinput_device {
        unsigned char           head;
        unsigned char           tail;
        struct input_event      buff[UINPUT_BUFFER_SIZE];
+       int                     ff_effects_max;
 
        struct uinput_request   *requests[UINPUT_NUM_REQUESTS];
        wait_queue_head_t       requests_waitq;
@@ -69,6 +79,7 @@ struct uinput_ff_upload {
        int                     request_id;
        int                     retval;
        struct ff_effect        effect;
+       struct ff_effect        old;
 };
 
 struct uinput_ff_erase {
@@ -98,33 +109,33 @@ struct uinput_ff_erase {
 #define UI_BEGIN_FF_ERASE      _IOWR(UINPUT_IOCTL_BASE, 202, struct uinput_ff_erase)
 #define UI_END_FF_ERASE                _IOW(UINPUT_IOCTL_BASE, 203, struct uinput_ff_erase)
 
-/* To write a force-feedback-capable driver, the upload_effect
+/*
+ * To write a force-feedback-capable driver, the upload_effect
  * and erase_effect callbacks in input_dev must be implemented.
  * The uinput driver will generate a fake input event when one of
  * these callbacks are invoked. The userspace code then uses
  * ioctls to retrieve additional parameters and send the return code.
  * The callback blocks until this return code is sent.
  *
- * The described callback mechanism is only used if EV_FF is set.
- * Otherwise, default implementations of upload_effect and erase_effect
- * are used.
+ * The described callback mechanism is only used if ff_effects_max
+ * is set.
  *
  * To implement upload_effect():
- *   1. Wait for an event with type==EV_UINPUT and code==UI_FF_UPLOAD.
+ *   1. Wait for an event with type == EV_UINPUT and code == UI_FF_UPLOAD.
  *      A request ID will be given in 'value'.
  *   2. Allocate a uinput_ff_upload struct, fill in request_id with
  *      the 'value' from the EV_UINPUT event.
  *   3. Issue a UI_BEGIN_FF_UPLOAD ioctl, giving it the
  *      uinput_ff_upload struct. It will be filled in with the
- *      ff_effect passed to upload_effect().
- *   4. Perform the effect upload, and place the modified ff_effect
*      and a return code back into the uinput_ff_upload struct.
+ *      ff_effects passed to upload_effect().
+ *   4. Perform the effect upload, and place a return code back into
       the uinput_ff_upload struct.
  *   5. Issue a UI_END_FF_UPLOAD ioctl, also giving it the
  *      uinput_ff_upload_effect struct. This will complete execution
  *      of our upload_effect() handler.
  *
  * To implement erase_effect():
- *   1. Wait for an event with type==EV_UINPUT and code==UI_FF_ERASE.
+ *   1. Wait for an event with type == EV_UINPUT and code == UI_FF_ERASE.
  *      A request ID will be given in 'value'.
  *   2. Allocate a uinput_ff_erase struct, fill in request_id with
  *      the 'value' from the EV_UINPUT event.
@@ -133,13 +144,13 @@ struct uinput_ff_erase {
  *      effect ID passed to erase_effect().
  *   4. Perform the effect erasure, and place a return code back
  *      into the uinput_ff_erase struct.
- *      and a return code back into the uinput_ff_erase struct.
  *   5. Issue a UI_END_FF_ERASE ioctl, also giving it the
  *      uinput_ff_erase_effect struct. This will complete execution
  *      of our erase_effect() handler.
  */
 
-/* This is the new event type, used only by uinput.
+/*
+ * This is the new event type, used only by uinput.
  * 'code' is UI_FF_UPLOAD or UI_FF_ERASE, and 'value'
  * is the unique request ID. This number was picked
  * arbitrarily, above EV_MAX (since the input system
index c18c60f3254ec998d33222aa1bd226c1f6314441..aa8d5b5e2e3e0b35b94df5824115640f972ce1d8 100644 (file)
@@ -1,12 +1,8 @@
 #ifndef _LINUX_UNISTD_H_
 #define _LINUX_UNISTD_H_
 
-#ifdef __KERNEL__
-extern int errno;
-#endif
-
 /*
- * Include machine specific syscallX macros
+ * Include machine specific syscall numbers
  */
 #include <asm/unistd.h>
 
index 13e1da0c538d209871bb1099169004aa24d52072..a4555fe3754cdb639775d5152307692d186a1151 100644 (file)
@@ -30,7 +30,65 @@ struct new_utsname {
        char domainname[65];
 };
 
-extern struct new_utsname system_utsname;
+#ifdef __KERNEL__
 
-extern struct rw_semaphore uts_sem;
+#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;
+};
+extern struct uts_namespace init_uts_ns;
+
+static inline void get_uts_ns(struct uts_namespace *ns)
+{
+       kref_get(&ns->kref);
+}
+
+#ifdef CONFIG_UTS_NS
+extern int unshare_utsname(unsigned long unshare_flags,
+                               struct uts_namespace **new_uts);
+extern int copy_utsname(int flags, struct task_struct *tsk);
+extern void free_uts_ns(struct kref *kref);
+
+static inline void put_uts_ns(struct uts_namespace *ns)
+{
+       kref_put(&ns->kref, free_uts_ns);
+}
+#else
+static inline int unshare_utsname(unsigned long unshare_flags,
+                       struct uts_namespace **new_uts)
+{
+       if (unshare_flags & CLONE_NEWUTS)
+               return -EINVAL;
+
+       return 0;
+}
+
+static inline int copy_utsname(int flags, struct task_struct *tsk)
+{
+       return 0;
+}
+static inline void put_uts_ns(struct uts_namespace *ns)
+{
+}
 #endif
+
+static inline struct new_utsname *utsname(void)
+{
+       return &current->nsproxy->uts_ns->name;
+}
+
+static inline struct new_utsname *init_utsname(void)
+{
+       return &init_uts_ns.name;
+}
+
+extern struct rw_semaphore uts_sem;
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_UTSNAME_H */
index 44c59da26ed2673c10c62fc54e50712cd6f3cff5..c5fdf62595483430ea42dec5d483a6503e11c312 100644 (file)
@@ -276,6 +276,82 @@ struct v4l2_fmtdesc
 
 #define V4L2_FMT_FLAG_COMPRESSED 0x0001
 
+#if 1
+       /* Experimental Frame Size and frame rate enumeration */
+/*
+ *     F R A M E   S I Z E   E N U M E R A T I O N
+ */
+enum v4l2_frmsizetypes
+{
+       V4L2_FRMSIZE_TYPE_DISCRETE      = 1,
+       V4L2_FRMSIZE_TYPE_CONTINUOUS    = 2,
+       V4L2_FRMSIZE_TYPE_STEPWISE      = 3,
+};
+
+struct v4l2_frmsize_discrete
+{
+       __u32                   width;          /* Frame width [pixel] */
+       __u32                   height;         /* Frame height [pixel] */
+};
+
+struct v4l2_frmsize_stepwise
+{
+       __u32                   min_width;      /* Minimum frame width [pixel] */
+       __u32                   max_width;      /* Maximum frame width [pixel] */
+       __u32                   step_width;     /* Frame width step size [pixel] */
+       __u32                   min_height;     /* Minimum frame height [pixel] */
+       __u32                   max_height;     /* Maximum frame height [pixel] */
+       __u32                   step_height;    /* Frame height step size [pixel] */
+};
+
+struct v4l2_frmsizeenum
+{
+       __u32                   index;          /* Frame size number */
+       __u32                   pixel_format;   /* Pixel format */
+       __u32                   type;           /* Frame size type the device supports. */
+
+       union {                                 /* Frame size */
+               struct v4l2_frmsize_discrete    discrete;
+               struct v4l2_frmsize_stepwise    stepwise;
+       };
+
+       __u32   reserved[2];                    /* Reserved space for future use */
+};
+
+/*
+ *     F R A M E   R A T E   E N U M E R A T I O N
+ */
+enum v4l2_frmivaltypes
+{
+       V4L2_FRMIVAL_TYPE_DISCRETE      = 1,
+       V4L2_FRMIVAL_TYPE_CONTINUOUS    = 2,
+       V4L2_FRMIVAL_TYPE_STEPWISE      = 3,
+};
+
+struct v4l2_frmival_stepwise
+{
+       struct v4l2_fract       min;            /* Minimum frame interval [s] */
+       struct v4l2_fract       max;            /* Maximum frame interval [s] */
+       struct v4l2_fract       step;           /* Frame interval step size [s] */
+};
+
+struct v4l2_frmivalenum
+{
+       __u32                   index;          /* Frame format index */
+       __u32                   pixel_format;   /* Pixel format */
+       __u32                   width;          /* Frame width */
+       __u32                   height;         /* Frame height */
+       __u32                   type;           /* Frame interval type the device supports. */
+
+       union {                                 /* Frame interval */
+               struct v4l2_fract               discrete;
+               struct v4l2_frmival_stepwise    stepwise;
+       };
+
+       __u32   reserved[2];                    /* Reserved space for future use */
+};
+#endif
+
 /*
  *     T I M E C O D E
  */
@@ -1249,6 +1325,10 @@ struct v4l2_streamparm
 #define VIDIOC_G_EXT_CTRLS     _IOWR ('V', 71, struct v4l2_ext_controls)
 #define VIDIOC_S_EXT_CTRLS     _IOWR ('V', 72, struct v4l2_ext_controls)
 #define VIDIOC_TRY_EXT_CTRLS   _IOWR ('V', 73, struct v4l2_ext_controls)
+#if 1
+#define VIDIOC_ENUM_FRAMESIZES _IOWR ('V', 74, struct v4l2_frmsizeenum)
+#define VIDIOC_ENUM_FRAMEINTERVALS     _IOWR ('V', 75, struct v4l2_frmivalenum)
+#endif
 
 #ifdef __OLD_VIDIOC_
 /* for compatibility, will go away some day */
index 1009d3fe1fc214e8eb920e207483ebdd7d35f1b3..37a1a41f5b65cbd06a0e71ccb17c3304160a9594 100644 (file)
@@ -84,4 +84,11 @@ void reset_vc(struct vc_data *vc);
 extern char con_buf[CON_BUF_SIZE];
 extern struct semaphore con_buf_sem;
 
+struct vt_spawn_console {
+       spinlock_t lock;
+       struct pid *pid;
+       int sig;
+};
+extern struct vt_spawn_console vt_spawn_con;
+
 #endif /* _VT_KERN_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 430afd05826975e4df9a65afe68e5b9729c1b11c..8ae7f744917b07123f80b7c38e3154729bf4b83d 100644 (file)
@@ -129,7 +129,8 @@ enum
 #define XFRM_MODE_TUNNEL 1
 #define XFRM_MODE_ROUTEOPTIMIZATION 2
 #define XFRM_MODE_IN_TRIGGER 3
-#define XFRM_MODE_MAX 4
+#define XFRM_MODE_BEET 4
+#define XFRM_MODE_MAX 5
 
 /* Netlink configuration messages.  */
 enum {
index 1fd4a2207574670846c9a85fbd43e99564d4e543..db8823d45a7d7936fc855706787bfce855cf723c 100644 (file)
@@ -18,7 +18,9 @@ enum audiochip {
        AUDIO_CHIP_TDA9874,
        AUDIO_CHIP_PIC16C54,
        /* Provided by msp3400.c */
-       AUDIO_CHIP_MSP34XX
+       AUDIO_CHIP_MSP34XX,
+       /* Provided by wm8775.c */
+       AUDIO_CHIP_WM8775
 };
 
 #endif /* AUDIOCHIP_H */
index 13e7a3c6d79476274c3eb993da753f94ba08b864..e0fe92b03a4e1141c297d6d741c26fa7d59f001d 100644 (file)
@@ -1,6 +1,5 @@
 header-y += inftl-user.h
 header-y += jffs2-user.h
+header-y += mtd-abi.h
 header-y += mtd-user.h
 header-y += nftl-user.h
-
-unifdef-y += mtd-abi.h
index b0a67b7ffdcd2697b1b281c4b3ff1c1733214216..f913c30d7b8976754e4c0008eb5c2db8eca44e08 100644 (file)
@@ -7,12 +7,6 @@
 #ifndef __MTD_ABI_H__
 #define __MTD_ABI_H__
 
-#ifndef __KERNEL__ 
-/* Urgh. The whole point of splitting this out into
-   separate files was to avoid #ifdef __KERNEL__ */
-#define __user
-#endif
-
 struct erase_info_user {
        uint32_t start;
        uint32_t length;
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 3570f9c9b1112be92a4e5b409abf5d6a5582d038..5dbf5e7e50a8c1c659261b796f7985150e6e9637 100644 (file)
 #  define print_var(X,Y...)
 #endif
 
-#define eprintk(X...)  printk(KERN_ERR "sstfb: " X)
-#define iprintk(X...)  printk(KERN_INFO "sstfb: " X)
-#define wprintk(X...)  printk(KERN_WARNING "sstfb: " X)
-
 #define BIT(x)         (1ul<<(x))
 #define POW2(x)                (1ul<<(x))
 
index f7a04d0daf077450e95926d68a4cb0ae52547c7e..10382931eead561940c023bd1b376863b9b11dab 100644 (file)
@@ -115,6 +115,15 @@ config SYSVIPC
          section 6.4 of the Linux Programmer's Guide, available from
          <http://www.tldp.org/guides.html>.
 
+config IPC_NS
+       bool "IPC Namespaces"
+       depends on SYSVIPC
+       default n
+       help
+         Support ipc namespaces.  This allows containers, i.e. virtual
+         environments, to use ipc namespaces to provide different ipc
+         objects for different servers.  If unsure, say N.
+
 config POSIX_MQUEUE
        bool "POSIX Message Queues"
        depends on NET && EXPERIMENTAL
@@ -182,6 +191,14 @@ config TASK_DELAY_ACCT
 
          Say N if unsure.
 
+config UTS_NS
+       bool "UTS Namespaces"
+       default n
+       help
+         Support uts namespaces.  This allows containers, i.e.
+         vservers, to use uts namespaces to provide different
+         uts info for different servers.  If unsure, say N.
+
 config AUDIT
        bool "Auditing support"
        depends on NET
index a06f037fa000a932d9de7b6f8dee909e5ce01720..919a80cb322e6f57dfa2be0a3bb727251bcd7e0e 100644 (file)
@@ -1,4 +1,3 @@
-#define __KERNEL_SYSCALLS__
 #include <linux/unistd.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
@@ -35,7 +34,7 @@ static int __init do_linuxrc(void * shell)
        (void) sys_open("/dev/console",O_RDWR,0);
        (void) sys_dup(0);
        (void) sys_dup(0);
-       return execve(shell, argv, envp_init);
+       return kernel_execve(shell, argv, envp_init);
 }
 
 static void __init handle_initrd(void)
index 2429e1bf8c60a1277edaed473760cfad8e486a1f..753dc54a664972ff0ae441ab8945c1345d563c2a 100644 (file)
@@ -20,7 +20,7 @@ static struct {
        int level;
        int chunk;
        char *device_names;
-} md_setup_args[MAX_MD_DEVS] __initdata;
+} md_setup_args[256] __initdata;
 
 static int md_setup_ents __initdata;
 
@@ -61,10 +61,6 @@ static int __init md_setup(char *str)
                return 0;
        }
        str1 = str;
-       if (minor >= MAX_MD_DEVS) {
-               printk(KERN_WARNING "md: md=%d, Minor device number too high.\n", minor);
-               return 0;
-       }
        for (ent=0 ; ent< md_setup_ents ; ent++)
                if (md_setup_args[ent].minor == minor &&
                    md_setup_args[ent].partitioned == partitioned) {
@@ -72,7 +68,7 @@ static int __init md_setup(char *str)
                               "Replacing previous definition.\n", partitioned?"d":"", minor);
                        break;
                }
-       if (ent >= MAX_MD_DEVS) {
+       if (ent >= ARRAY_SIZE(md_setup_args)) {
                printk(KERN_WARNING "md: md=%s%d - too many md initialisations\n", partitioned?"d":"", minor);
                return 0;
        }
index 0766e69712b2a86efa74caf3c5bd487bbbcd3753..ee123243fb530b4d4e589f731c5bfa4652148dc8 100644 (file)
@@ -9,8 +9,6 @@
  *  Simplified starting of init:  Michael A. Griffith <grif@acm.org> 
  */
 
-#define __KERNEL_SYSCALLS__
-
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/proc_fs.h>
@@ -703,7 +701,7 @@ static void do_pre_smp_initcalls(void)
 static void run_init_process(char *init_filename)
 {
        argv_init[0] = init_filename;
-       execve(init_filename, argv_init, envp_init);
+       kernel_execve(init_filename, argv_init, envp_init);
 }
 
 static int init(void * unused)
@@ -723,6 +721,8 @@ static int init(void * unused)
         */
        child_reaper = current;
 
+       cad_pid = task_pid(current);
+
        smp_prepare_cpus(max_cpus);
 
        do_pre_smp_initcalls();
index e290802c6bd2c4920245d82cbe7b549a78cd1593..8f28344d9c70fda49300ac1455e98e086913b481 100644 (file)
 #include <linux/utsname.h>
 #include <linux/utsrelease.h>
 #include <linux/version.h>
+#include <linux/sched.h>
 
 #define version(a) Version_ ## a
 #define version_string(a) version(a)
 
 int version_string(LINUX_VERSION_CODE);
 
-struct new_utsname system_utsname = {
-       .sysname        = UTS_SYSNAME,
-       .nodename       = UTS_NODENAME,
-       .release        = UTS_RELEASE,
-       .version        = UTS_VERSION,
-       .machine        = UTS_MACHINE,
-       .domainname     = UTS_DOMAINNAME,
+struct uts_namespace init_uts_ns = {
+       .kref = {
+               .refcount       = ATOMIC_INIT(2),
+       },
+       .name = {
+               .sysname        = UTS_SYSNAME,
+               .nodename       = UTS_NODENAME,
+               .release        = UTS_RELEASE,
+               .version        = UTS_VERSION,
+               .machine        = UTS_MACHINE,
+               .domainname     = UTS_DOMAINNAME,
+       },
 };
-
-EXPORT_SYMBOL(system_utsname);
+EXPORT_SYMBOL_GPL(init_uts_ns);
 
 const char linux_banner[] =
        "Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
index d75d0ba833609bd58c6fc7a692f8b934f7b735ff..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:
@@ -73,7 +73,7 @@ struct mqueue_inode_info {
        struct mq_attr attr;
 
        struct sigevent notify;
-       pid_t notify_owner;
+       struct pid* notify_owner;
        struct user_struct *user;       /* user who created, for accounting */
        struct sock *notify_sock;
        struct sk_buff *notify_cookie;
@@ -134,7 +134,7 @@ static struct inode *mqueue_get_inode(struct super_block *sb, int mode,
                        INIT_LIST_HEAD(&info->e_wait_q[0].list);
                        INIT_LIST_HEAD(&info->e_wait_q[1].list);
                        info->messages = NULL;
-                       info->notify_owner = 0;
+                       info->notify_owner = NULL;
                        info->qsize = 0;
                        info->user = NULL;      /* set when all is ok */
                        memset(&info->attr, 0, sizeof(info->attr));
@@ -338,7 +338,7 @@ static ssize_t mqueue_read_file(struct file *filp, char __user *u_data,
                        (info->notify_owner &&
                         info->notify.sigev_notify == SIGEV_SIGNAL) ?
                                info->notify.sigev_signo : 0,
-                       info->notify_owner);
+                       pid_nr(info->notify_owner));
        spin_unlock(&info->lock);
        buffer[sizeof(buffer)-1] = '\0';
        slen = strlen(buffer)+1;
@@ -363,7 +363,7 @@ static int mqueue_flush_file(struct file *filp, fl_owner_t id)
        struct mqueue_inode_info *info = MQUEUE_I(filp->f_dentry->d_inode);
 
        spin_lock(&info->lock);
-       if (current->tgid == info->notify_owner)
+       if (task_tgid(current) == info->notify_owner)
                remove_notification(info);
 
        spin_unlock(&info->lock);
@@ -518,8 +518,8 @@ static void __do_notify(struct mqueue_inode_info *info)
                        sig_i.si_pid = current->tgid;
                        sig_i.si_uid = current->uid;
 
-                       kill_proc_info(info->notify.sigev_signo,
-                                      &sig_i, info->notify_owner);
+                       kill_pid_info(info->notify.sigev_signo,
+                                     &sig_i, info->notify_owner);
                        break;
                case SIGEV_THREAD:
                        set_cookie(info->notify_cookie, NOTIFY_WOKENUP);
@@ -528,7 +528,8 @@ static void __do_notify(struct mqueue_inode_info *info)
                        break;
                }
                /* after notification unregisters process */
-               info->notify_owner = 0;
+               put_pid(info->notify_owner);
+               info->notify_owner = NULL;
        }
        wake_up(&info->wait_q);
 }
@@ -566,12 +567,13 @@ static long prepare_timeout(const struct timespec __user *u_arg)
 
 static void remove_notification(struct mqueue_inode_info *info)
 {
-       if (info->notify_owner != 0 &&
+       if (info->notify_owner != NULL &&
            info->notify.sigev_notify == SIGEV_THREAD) {
                set_cookie(info->notify_cookie, NOTIFY_REMOVED);
                netlink_sendskb(info->notify_sock, info->notify_cookie, 0);
        }
-       info->notify_owner = 0;
+       put_pid(info->notify_owner);
+       info->notify_owner = NULL;
 }
 
 static int mq_attr_ok(struct mq_attr *attr)
@@ -1062,11 +1064,11 @@ retry:
        ret = 0;
        spin_lock(&info->lock);
        if (u_notification == NULL) {
-               if (info->notify_owner == current->tgid) {
+               if (info->notify_owner == task_tgid(current)) {
                        remove_notification(info);
                        inode->i_atime = inode->i_ctime = CURRENT_TIME;
                }
-       } else if (info->notify_owner != 0) {
+       } else if (info->notify_owner != NULL) {
                ret = -EBUSY;
        } else {
                switch (notification.sigev_notify) {
@@ -1086,7 +1088,8 @@ retry:
                        info->notify.sigev_notify = SIGEV_SIGNAL;
                        break;
                }
-               info->notify_owner = current->tgid;
+
+               info->notify_owner = get_pid(task_tgid(current));
                inode->i_atime = inode->i_ctime = CURRENT_TIME;
        }
        spin_unlock(&info->lock);
index 2b4fccf8ea55a9a2babc5f92b36fcdf6a1dd5a7d..5b213d952545e82684dc1d3f212f311ad3348790 100644 (file)
--- a/ipc/msg.c
+++ b/ipc/msg.c
  *
  * support for audit of ipc object properties and permission changes
  * Dustin Kirkland <dustin.kirkland@us.ibm.com>
+ *
+ * namespaces support
+ * OpenVZ, SWsoft Inc.
+ * Pavel Emelianov <xemul@openvz.org>
  */
 
 #include <linux/capability.h>
 #include <linux/audit.h>
 #include <linux/seq_file.h>
 #include <linux/mutex.h>
+#include <linux/nsproxy.h>
 
 #include <asm/current.h>
 #include <asm/uaccess.h>
 #include "util.h"
 
-/* sysctl: */
-int msg_ctlmax = MSGMAX;
-int msg_ctlmnb = MSGMNB;
-int msg_ctlmni = MSGMNI;
-
 /*
  * one msg_receiver structure for each sleeping receiver:
  */
@@ -69,30 +69,75 @@ struct msg_sender {
 static atomic_t msg_bytes =    ATOMIC_INIT(0);
 static atomic_t msg_hdrs =     ATOMIC_INIT(0);
 
-static struct ipc_ids msg_ids;
+static struct ipc_ids init_msg_ids;
 
-#define msg_lock(id)           ((struct msg_queue *)ipc_lock(&msg_ids, id))
-#define msg_unlock(msq)                ipc_unlock(&(msq)->q_perm)
-#define msg_rmid(id)           ((struct msg_queue *)ipc_rmid(&msg_ids, id))
-#define msg_checkid(msq, msgid)        ipc_checkid(&msg_ids, &msq->q_perm, msgid)
-#define msg_buildid(id, seq)   ipc_buildid(&msg_ids, id, seq)
+#define msg_ids(ns)    (*((ns)->ids[IPC_MSG_IDS]))
 
-static void freeque(struct msg_queue *msq, int id);
-static int newque(key_t key, int msgflg);
+#define msg_lock(ns, id)       ((struct msg_queue*)ipc_lock(&msg_ids(ns), id))
+#define msg_unlock(msq)                ipc_unlock(&(msq)->q_perm)
+#define msg_rmid(ns, id)       ((struct msg_queue*)ipc_rmid(&msg_ids(ns), id))
+#define msg_checkid(ns, msq, msgid)    \
+       ipc_checkid(&msg_ids(ns), &msq->q_perm, msgid)
+#define msg_buildid(ns, id, seq) \
+       ipc_buildid(&msg_ids(ns), id, seq)
+
+static void freeque (struct ipc_namespace *ns, struct msg_queue *msq, int id);
+static int newque (struct ipc_namespace *ns, key_t key, int msgflg);
 #ifdef CONFIG_PROC_FS
 static int sysvipc_msg_proc_show(struct seq_file *s, void *it);
 #endif
 
+static void __ipc_init __msg_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
+{
+       ns->ids[IPC_MSG_IDS] = ids;
+       ns->msg_ctlmax = MSGMAX;
+       ns->msg_ctlmnb = MSGMNB;
+       ns->msg_ctlmni = MSGMNI;
+       ipc_init_ids(ids, ns->msg_ctlmni);
+}
+
+#ifdef CONFIG_IPC_NS
+int msg_init_ns(struct ipc_namespace *ns)
+{
+       struct ipc_ids *ids;
+
+       ids = kmalloc(sizeof(struct ipc_ids), GFP_KERNEL);
+       if (ids == NULL)
+               return -ENOMEM;
+
+       __msg_init_ns(ns, ids);
+       return 0;
+}
+
+void msg_exit_ns(struct ipc_namespace *ns)
+{
+       int i;
+       struct msg_queue *msq;
+
+       mutex_lock(&msg_ids(ns).mutex);
+       for (i = 0; i <= msg_ids(ns).max_id; i++) {
+               msq = msg_lock(ns, i);
+               if (msq == NULL)
+                       continue;
+
+               freeque(ns, msq, i);
+       }
+       mutex_unlock(&msg_ids(ns).mutex);
+
+       kfree(ns->ids[IPC_MSG_IDS]);
+       ns->ids[IPC_MSG_IDS] = NULL;
+}
+#endif
+
 void __init msg_init(void)
 {
-       ipc_init_ids(&msg_ids, msg_ctlmni);
+       __msg_init_ns(&init_ipc_ns, &init_msg_ids);
        ipc_init_proc_interface("sysvipc/msg",
                                "       key      msqid perms      cbytes       qnum lspid lrpid   uid   gid  cuid  cgid      stime      rtime      ctime\n",
-                               &msg_ids,
-                               sysvipc_msg_proc_show);
+                               IPC_MSG_IDS, sysvipc_msg_proc_show);
 }
 
-static int newque(key_t key, int msgflg)
+static int newque (struct ipc_namespace *ns, key_t key, int msgflg)
 {
        struct msg_queue *msq;
        int id, retval;
@@ -111,18 +156,18 @@ static int newque(key_t key, int msgflg)
                return retval;
        }
 
-       id = ipc_addid(&msg_ids, &msq->q_perm, msg_ctlmni);
+       id = ipc_addid(&msg_ids(ns), &msq->q_perm, ns->msg_ctlmni);
        if (id == -1) {
                security_msg_queue_free(msq);
                ipc_rcu_putref(msq);
                return -ENOSPC;
        }
 
-       msq->q_id = msg_buildid(id, msq->q_perm.seq);
+       msq->q_id = msg_buildid(ns, id, msq->q_perm.seq);
        msq->q_stime = msq->q_rtime = 0;
        msq->q_ctime = get_seconds();
        msq->q_cbytes = msq->q_qnum = 0;
-       msq->q_qbytes = msg_ctlmnb;
+       msq->q_qbytes = ns->msg_ctlmnb;
        msq->q_lspid = msq->q_lrpid = 0;
        INIT_LIST_HEAD(&msq->q_messages);
        INIT_LIST_HEAD(&msq->q_receivers);
@@ -186,13 +231,13 @@ static void expunge_all(struct msg_queue *msq, int res)
  * msg_ids.mutex and the spinlock for this message queue is hold
  * before freeque() is called. msg_ids.mutex remains locked on exit.
  */
-static void freeque(struct msg_queue *msq, int id)
+static void freeque(struct ipc_namespace *ns, struct msg_queue *msq, int id)
 {
        struct list_head *tmp;
 
        expunge_all(msq, -EIDRM);
        ss_wakeup(&msq->q_senders, 1);
-       msq = msg_rmid(id);
+       msq = msg_rmid(ns, id);
        msg_unlock(msq);
 
        tmp = msq->q_messages.next;
@@ -212,24 +257,27 @@ asmlinkage long sys_msgget(key_t key, int msgflg)
 {
        struct msg_queue *msq;
        int id, ret = -EPERM;
+       struct ipc_namespace *ns;
+
+       ns = current->nsproxy->ipc_ns;
        
-       mutex_lock(&msg_ids.mutex);
+       mutex_lock(&msg_ids(ns).mutex);
        if (key == IPC_PRIVATE) 
-               ret = newque(key, msgflg);
-       else if ((id = ipc_findkey(&msg_ids, key)) == -1) { /* key not used */
+               ret = newque(ns, key, msgflg);
+       else if ((id = ipc_findkey(&msg_ids(ns), key)) == -1) { /* key not used */
                if (!(msgflg & IPC_CREAT))
                        ret = -ENOENT;
                else
-                       ret = newque(key, msgflg);
+                       ret = newque(ns, key, msgflg);
        } else if (msgflg & IPC_CREAT && msgflg & IPC_EXCL) {
                ret = -EEXIST;
        } else {
-               msq = msg_lock(id);
+               msq = msg_lock(ns, id);
                BUG_ON(msq == NULL);
                if (ipcperms(&msq->q_perm, msgflg))
                        ret = -EACCES;
                else {
-                       int qid = msg_buildid(id, msq->q_perm.seq);
+                       int qid = msg_buildid(ns, id, msq->q_perm.seq);
 
                        ret = security_msg_queue_associate(msq, msgflg);
                        if (!ret)
@@ -237,7 +285,7 @@ asmlinkage long sys_msgget(key_t key, int msgflg)
                }
                msg_unlock(msq);
        }
-       mutex_unlock(&msg_ids.mutex);
+       mutex_unlock(&msg_ids(ns).mutex);
 
        return ret;
 }
@@ -341,11 +389,13 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
        struct msq_setbuf setbuf;
        struct msg_queue *msq;
        int err, version;
+       struct ipc_namespace *ns;
 
        if (msqid < 0 || cmd < 0)
                return -EINVAL;
 
        version = ipc_parse_version(&cmd);
+       ns = current->nsproxy->ipc_ns;
 
        switch (cmd) {
        case IPC_INFO:
@@ -366,14 +416,14 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
                        return err;
 
                memset(&msginfo, 0, sizeof(msginfo));
-               msginfo.msgmni = msg_ctlmni;
-               msginfo.msgmax = msg_ctlmax;
-               msginfo.msgmnb = msg_ctlmnb;
+               msginfo.msgmni = ns->msg_ctlmni;
+               msginfo.msgmax = ns->msg_ctlmax;
+               msginfo.msgmnb = ns->msg_ctlmnb;
                msginfo.msgssz = MSGSSZ;
                msginfo.msgseg = MSGSEG;
-               mutex_lock(&msg_ids.mutex);
+               mutex_lock(&msg_ids(ns).mutex);
                if (cmd == MSG_INFO) {
-                       msginfo.msgpool = msg_ids.in_use;
+                       msginfo.msgpool = msg_ids(ns).in_use;
                        msginfo.msgmap = atomic_read(&msg_hdrs);
                        msginfo.msgtql = atomic_read(&msg_bytes);
                } else {
@@ -381,8 +431,8 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
                        msginfo.msgpool = MSGPOOL;
                        msginfo.msgtql = MSGTQL;
                }
-               max_id = msg_ids.max_id;
-               mutex_unlock(&msg_ids.mutex);
+               max_id = msg_ids(ns).max_id;
+               mutex_unlock(&msg_ids(ns).mutex);
                if (copy_to_user(buf, &msginfo, sizeof(struct msginfo)))
                        return -EFAULT;
                return (max_id < 0) ? 0 : max_id;
@@ -395,20 +445,20 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
 
                if (!buf)
                        return -EFAULT;
-               if (cmd == MSG_STAT && msqid >= msg_ids.entries->size)
+               if (cmd == MSG_STAT && msqid >= msg_ids(ns).entries->size)
                        return -EINVAL;
 
                memset(&tbuf, 0, sizeof(tbuf));
 
-               msq = msg_lock(msqid);
+               msq = msg_lock(ns, msqid);
                if (msq == NULL)
                        return -EINVAL;
 
                if (cmd == MSG_STAT) {
-                       success_return = msg_buildid(msqid, msq->q_perm.seq);
+                       success_return = msg_buildid(ns, msqid, msq->q_perm.seq);
                } else {
                        err = -EIDRM;
-                       if (msg_checkid(msq, msqid))
+                       if (msg_checkid(ns, msq, msqid))
                                goto out_unlock;
                        success_return = 0;
                }
@@ -446,14 +496,14 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
                return  -EINVAL;
        }
 
-       mutex_lock(&msg_ids.mutex);
-       msq = msg_lock(msqid);
+       mutex_lock(&msg_ids(ns).mutex);
+       msq = msg_lock(ns, msqid);
        err = -EINVAL;
        if (msq == NULL)
                goto out_up;
 
        err = -EIDRM;
-       if (msg_checkid(msq, msqid))
+       if (msg_checkid(ns, msq, msqid))
                goto out_unlock_up;
        ipcp = &msq->q_perm;
 
@@ -481,7 +531,7 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
        case IPC_SET:
        {
                err = -EPERM;
-               if (setbuf.qbytes > msg_ctlmnb && !capable(CAP_SYS_RESOURCE))
+               if (setbuf.qbytes > ns->msg_ctlmnb && !capable(CAP_SYS_RESOURCE))
                        goto out_unlock_up;
 
                msq->q_qbytes = setbuf.qbytes;
@@ -503,12 +553,12 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
                break;
        }
        case IPC_RMID:
-               freeque(msq, msqid);
+               freeque(ns, msq, msqid);
                break;
        }
        err = 0;
 out_up:
-       mutex_unlock(&msg_ids.mutex);
+       mutex_unlock(&msg_ids(ns).mutex);
        return err;
 out_unlock_up:
        msg_unlock(msq);
@@ -582,8 +632,11 @@ sys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz, int msgflg)
        struct msg_msg *msg;
        long mtype;
        int err;
+       struct ipc_namespace *ns;
+
+       ns = current->nsproxy->ipc_ns;
 
-       if (msgsz > msg_ctlmax || (long) msgsz < 0 || msqid < 0)
+       if (msgsz > ns->msg_ctlmax || (long) msgsz < 0 || msqid < 0)
                return -EINVAL;
        if (get_user(mtype, &msgp->mtype))
                return -EFAULT;
@@ -597,13 +650,13 @@ sys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz, int msgflg)
        msg->m_type = mtype;
        msg->m_ts = msgsz;
 
-       msq = msg_lock(msqid);
+       msq = msg_lock(ns, msqid);
        err = -EINVAL;
        if (msq == NULL)
                goto out_free;
 
        err= -EIDRM;
-       if (msg_checkid(msq, msqid))
+       if (msg_checkid(ns, msq, msqid))
                goto out_unlock_free;
 
        for (;;) {
@@ -694,17 +747,19 @@ asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz,
        struct msg_queue *msq;
        struct msg_msg *msg;
        int mode;
+       struct ipc_namespace *ns;
 
        if (msqid < 0 || (long) msgsz < 0)
                return -EINVAL;
        mode = convert_mode(&msgtyp, msgflg);
+       ns = current->nsproxy->ipc_ns;
 
-       msq = msg_lock(msqid);
+       msq = msg_lock(ns, msqid);
        if (msq == NULL)
                return -EINVAL;
 
        msg = ERR_PTR(-EIDRM);
-       if (msg_checkid(msq, msqid))
+       if (msg_checkid(ns, msq, msqid))
                goto out_unlock;
 
        for (;;) {
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 6013c751156fe81bee30536bef27bab7792eb1bb..0dafcc455f920888fe13a474b926ad0bd6825a11 100644 (file)
--- a/ipc/sem.c
+++ b/ipc/sem.c
  *
  * support for audit of ipc object properties and permission changes
  * Dustin Kirkland <dustin.kirkland@us.ibm.com>
+ *
+ * namespaces support
+ * OpenVZ, SWsoft Inc.
+ * Pavel Emelianov <xemul@openvz.org>
  */
 
 #include <linux/slab.h>
 #include <linux/capability.h>
 #include <linux/seq_file.h>
 #include <linux/mutex.h>
+#include <linux/nsproxy.h>
 
 #include <asm/uaccess.h>
 #include "util.h"
 
+#define sem_ids(ns)    (*((ns)->ids[IPC_SEM_IDS]))
+
+#define sem_lock(ns, id)       ((struct sem_array*)ipc_lock(&sem_ids(ns), id))
+#define sem_unlock(sma)                ipc_unlock(&(sma)->sem_perm)
+#define sem_rmid(ns, id)       ((struct sem_array*)ipc_rmid(&sem_ids(ns), id))
+#define sem_checkid(ns, sma, semid)    \
+       ipc_checkid(&sem_ids(ns),&sma->sem_perm,semid)
+#define sem_buildid(ns, id, seq) \
+       ipc_buildid(&sem_ids(ns), id, seq)
 
-#define sem_lock(id)   ((struct sem_array*)ipc_lock(&sem_ids,id))
-#define sem_unlock(sma)        ipc_unlock(&(sma)->sem_perm)
-#define sem_rmid(id)   ((struct sem_array*)ipc_rmid(&sem_ids,id))
-#define sem_checkid(sma, semid)        \
-       ipc_checkid(&sem_ids,&sma->sem_perm,semid)
-#define sem_buildid(id, seq) \
-       ipc_buildid(&sem_ids, id, seq)
-static struct ipc_ids sem_ids;
+static struct ipc_ids init_sem_ids;
 
-static int newary (key_t, int, int);
-static void freeary (struct sem_array *sma, int id);
+static int newary(struct ipc_namespace *, key_t, int, int);
+static void freeary(struct ipc_namespace *ns, struct sem_array *sma, int id);
 #ifdef CONFIG_PROC_FS
 static int sysvipc_sem_proc_show(struct seq_file *s, void *it);
 #endif
@@ -110,22 +117,61 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it);
  *     
  */
 
-int sem_ctls[4] = {SEMMSL, SEMMNS, SEMOPM, SEMMNI};
-#define sc_semmsl      (sem_ctls[0])
-#define sc_semmns      (sem_ctls[1])
-#define sc_semopm      (sem_ctls[2])
-#define sc_semmni      (sem_ctls[3])
+#define sc_semmsl      sem_ctls[0]
+#define sc_semmns      sem_ctls[1]
+#define sc_semopm      sem_ctls[2]
+#define sc_semmni      sem_ctls[3]
 
-static int used_sems;
+static void __ipc_init __sem_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
+{
+       ns->ids[IPC_SEM_IDS] = ids;
+       ns->sc_semmsl = SEMMSL;
+       ns->sc_semmns = SEMMNS;
+       ns->sc_semopm = SEMOPM;
+       ns->sc_semmni = SEMMNI;
+       ns->used_sems = 0;
+       ipc_init_ids(ids, ns->sc_semmni);
+}
+
+#ifdef CONFIG_IPC_NS
+int sem_init_ns(struct ipc_namespace *ns)
+{
+       struct ipc_ids *ids;
+
+       ids = kmalloc(sizeof(struct ipc_ids), GFP_KERNEL);
+       if (ids == NULL)
+               return -ENOMEM;
+
+       __sem_init_ns(ns, ids);
+       return 0;
+}
+
+void sem_exit_ns(struct ipc_namespace *ns)
+{
+       int i;
+       struct sem_array *sma;
+
+       mutex_lock(&sem_ids(ns).mutex);
+       for (i = 0; i <= sem_ids(ns).max_id; i++) {
+               sma = sem_lock(ns, i);
+               if (sma == NULL)
+                       continue;
+
+               freeary(ns, sma, i);
+       }
+       mutex_unlock(&sem_ids(ns).mutex);
+
+       kfree(ns->ids[IPC_SEM_IDS]);
+       ns->ids[IPC_SEM_IDS] = NULL;
+}
+#endif
 
 void __init sem_init (void)
 {
-       used_sems = 0;
-       ipc_init_ids(&sem_ids,sc_semmni);
+       __sem_init_ns(&init_ipc_ns, &init_sem_ids);
        ipc_init_proc_interface("sysvipc/sem",
                                "       key      semid perms      nsems   uid   gid  cuid  cgid      otime      ctime\n",
-                               &sem_ids,
-                               sysvipc_sem_proc_show);
+                               IPC_SEM_IDS, sysvipc_sem_proc_show);
 }
 
 /*
@@ -162,7 +208,7 @@ void __init sem_init (void)
  */
 #define IN_WAKEUP      1
 
-static int newary (key_t key, int nsems, int semflg)
+static int newary (struct ipc_namespace *ns, key_t key, int nsems, int semflg)
 {
        int id;
        int retval;
@@ -171,7 +217,7 @@ static int newary (key_t key, int nsems, int semflg)
 
        if (!nsems)
                return -EINVAL;
-       if (used_sems + nsems > sc_semmns)
+       if (ns->used_sems + nsems > ns->sc_semmns)
                return -ENOSPC;
 
        size = sizeof (*sma) + nsems * sizeof (struct sem);
@@ -191,15 +237,15 @@ static int newary (key_t key, int nsems, int semflg)
                return retval;
        }
 
-       id = ipc_addid(&sem_ids, &sma->sem_perm, sc_semmni);
+       id = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni);
        if(id == -1) {
                security_sem_free(sma);
                ipc_rcu_putref(sma);
                return -ENOSPC;
        }
-       used_sems += nsems;
+       ns->used_sems += nsems;
 
-       sma->sem_id = sem_buildid(id, sma->sem_perm.seq);
+       sma->sem_id = sem_buildid(ns, id, sma->sem_perm.seq);
        sma->sem_base = (struct sem *) &sma[1];
        /* sma->sem_pending = NULL; */
        sma->sem_pending_last = &sma->sem_pending;
@@ -215,29 +261,32 @@ asmlinkage long sys_semget (key_t key, int nsems, int semflg)
 {
        int id, err = -EINVAL;
        struct sem_array *sma;
+       struct ipc_namespace *ns;
 
-       if (nsems < 0 || nsems > sc_semmsl)
+       ns = current->nsproxy->ipc_ns;
+
+       if (nsems < 0 || nsems > ns->sc_semmsl)
                return -EINVAL;
-       mutex_lock(&sem_ids.mutex);
+       mutex_lock(&sem_ids(ns).mutex);
        
        if (key == IPC_PRIVATE) {
-               err = newary(key, nsems, semflg);
-       } else if ((id = ipc_findkey(&sem_ids, key)) == -1) {  /* key not used */
+               err = newary(ns, key, nsems, semflg);
+       } else if ((id = ipc_findkey(&sem_ids(ns), key)) == -1) {  /* key not used */
                if (!(semflg & IPC_CREAT))
                        err = -ENOENT;
                else
-                       err = newary(key, nsems, semflg);
+                       err = newary(ns, key, nsems, semflg);
        } else if (semflg & IPC_CREAT && semflg & IPC_EXCL) {
                err = -EEXIST;
        } else {
-               sma = sem_lock(id);
+               sma = sem_lock(ns, id);
                BUG_ON(sma==NULL);
                if (nsems > sma->sem_nsems)
                        err = -EINVAL;
                else if (ipcperms(&sma->sem_perm, semflg))
                        err = -EACCES;
                else {
-                       int semid = sem_buildid(id, sma->sem_perm.seq);
+                       int semid = sem_buildid(ns, id, sma->sem_perm.seq);
                        err = security_sem_associate(sma, semflg);
                        if (!err)
                                err = semid;
@@ -245,7 +294,7 @@ asmlinkage long sys_semget (key_t key, int nsems, int semflg)
                sem_unlock(sma);
        }
 
-       mutex_unlock(&sem_ids.mutex);
+       mutex_unlock(&sem_ids(ns).mutex);
        return err;
 }
 
@@ -444,7 +493,7 @@ static int count_semzcnt (struct sem_array * sma, ushort semnum)
  * the spinlock for this semaphore set hold. sem_ids.mutex remains locked
  * on exit.
  */
-static void freeary (struct sem_array *sma, int id)
+static void freeary (struct ipc_namespace *ns, struct sem_array *sma, int id)
 {
        struct sem_undo *un;
        struct sem_queue *q;
@@ -472,10 +521,10 @@ static void freeary (struct sem_array *sma, int id)
        }
 
        /* Remove the semaphore set from the ID array*/
-       sma = sem_rmid(id);
+       sma = sem_rmid(ns, id);
        sem_unlock(sma);
 
-       used_sems -= sma->sem_nsems;
+       ns->used_sems -= sma->sem_nsems;
        size = sizeof (*sma) + sma->sem_nsems * sizeof (struct sem);
        security_sem_free(sma);
        ipc_rcu_putref(sma);
@@ -503,7 +552,8 @@ static unsigned long copy_semid_to_user(void __user *buf, struct semid64_ds *in,
        }
 }
 
-static int semctl_nolock(int semid, int semnum, int cmd, int version, union semun arg)
+static int semctl_nolock(struct ipc_namespace *ns, int semid, int semnum,
+               int cmd, int version, union semun arg)
 {
        int err = -EINVAL;
        struct sem_array *sma;
@@ -520,24 +570,24 @@ static int semctl_nolock(int semid, int semnum, int cmd, int version, union semu
                        return err;
                
                memset(&seminfo,0,sizeof(seminfo));
-               seminfo.semmni = sc_semmni;
-               seminfo.semmns = sc_semmns;
-               seminfo.semmsl = sc_semmsl;
-               seminfo.semopm = sc_semopm;
+               seminfo.semmni = ns->sc_semmni;
+               seminfo.semmns = ns->sc_semmns;
+               seminfo.semmsl = ns->sc_semmsl;
+               seminfo.semopm = ns->sc_semopm;
                seminfo.semvmx = SEMVMX;
                seminfo.semmnu = SEMMNU;
                seminfo.semmap = SEMMAP;
                seminfo.semume = SEMUME;
-               mutex_lock(&sem_ids.mutex);
+               mutex_lock(&sem_ids(ns).mutex);
                if (cmd == SEM_INFO) {
-                       seminfo.semusz = sem_ids.in_use;
-                       seminfo.semaem = used_sems;
+                       seminfo.semusz = sem_ids(ns).in_use;
+                       seminfo.semaem = ns->used_sems;
                } else {
                        seminfo.semusz = SEMUSZ;
                        seminfo.semaem = SEMAEM;
                }
-               max_id = sem_ids.max_id;
-               mutex_unlock(&sem_ids.mutex);
+               max_id = sem_ids(ns).max_id;
+               mutex_unlock(&sem_ids(ns).mutex);
                if (copy_to_user (arg.__buf, &seminfo, sizeof(struct seminfo))) 
                        return -EFAULT;
                return (max_id < 0) ? 0: max_id;
@@ -547,12 +597,12 @@ static int semctl_nolock(int semid, int semnum, int cmd, int version, union semu
                struct semid64_ds tbuf;
                int id;
 
-               if(semid >= sem_ids.entries->size)
+               if(semid >= sem_ids(ns).entries->size)
                        return -EINVAL;
 
                memset(&tbuf,0,sizeof(tbuf));
 
-               sma = sem_lock(semid);
+               sma = sem_lock(ns, semid);
                if(sma == NULL)
                        return -EINVAL;
 
@@ -564,7 +614,7 @@ static int semctl_nolock(int semid, int semnum, int cmd, int version, union semu
                if (err)
                        goto out_unlock;
 
-               id = sem_buildid(semid, sma->sem_perm.seq);
+               id = sem_buildid(ns, semid, sma->sem_perm.seq);
 
                kernel_to_ipc64_perm(&sma->sem_perm, &tbuf.sem_perm);
                tbuf.sem_otime  = sma->sem_otime;
@@ -584,7 +634,8 @@ out_unlock:
        return err;
 }
 
-static int semctl_main(int semid, int semnum, int cmd, int version, union semun arg)
+static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
+               int cmd, int version, union semun arg)
 {
        struct sem_array *sma;
        struct sem* curr;
@@ -593,14 +644,14 @@ static int semctl_main(int semid, int semnum, int cmd, int version, union semun
        ushort* sem_io = fast_sem_io;
        int nsems;
 
-       sma = sem_lock(semid);
+       sma = sem_lock(ns, semid);
        if(sma==NULL)
                return -EINVAL;
 
        nsems = sma->sem_nsems;
 
        err=-EIDRM;
-       if (sem_checkid(sma,semid))
+       if (sem_checkid(ns,sma,semid))
                goto out_unlock;
 
        err = -EACCES;
@@ -802,7 +853,8 @@ static inline unsigned long copy_semid_from_user(struct sem_setbuf *out, void __
        }
 }
 
-static int semctl_down(int semid, int semnum, int cmd, int version, union semun arg)
+static int semctl_down(struct ipc_namespace *ns, int semid, int semnum,
+               int cmd, int version, union semun arg)
 {
        struct sem_array *sma;
        int err;
@@ -813,11 +865,11 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun
                if(copy_semid_from_user (&setbuf, arg.buf, version))
                        return -EFAULT;
        }
-       sma = sem_lock(semid);
+       sma = sem_lock(ns, semid);
        if(sma==NULL)
                return -EINVAL;
 
-       if (sem_checkid(sma,semid)) {
+       if (sem_checkid(ns,sma,semid)) {
                err=-EIDRM;
                goto out_unlock;
        }       
@@ -844,7 +896,7 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun
 
        switch(cmd){
        case IPC_RMID:
-               freeary(sma, semid);
+               freeary(ns, sma, semid);
                err = 0;
                break;
        case IPC_SET:
@@ -872,17 +924,19 @@ asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg)
 {
        int err = -EINVAL;
        int version;
+       struct ipc_namespace *ns;
 
        if (semid < 0)
                return -EINVAL;
 
        version = ipc_parse_version(&cmd);
+       ns = current->nsproxy->ipc_ns;
 
        switch(cmd) {
        case IPC_INFO:
        case SEM_INFO:
        case SEM_STAT:
-               err = semctl_nolock(semid,semnum,cmd,version,arg);
+               err = semctl_nolock(ns,semid,semnum,cmd,version,arg);
                return err;
        case GETALL:
        case GETVAL:
@@ -892,13 +946,13 @@ asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg)
        case IPC_STAT:
        case SETVAL:
        case SETALL:
-               err = semctl_main(semid,semnum,cmd,version,arg);
+               err = semctl_main(ns,semid,semnum,cmd,version,arg);
                return err;
        case IPC_RMID:
        case IPC_SET:
-               mutex_lock(&sem_ids.mutex);
-               err = semctl_down(semid,semnum,cmd,version,arg);
-               mutex_unlock(&sem_ids.mutex);
+               mutex_lock(&sem_ids(ns).mutex);
+               err = semctl_down(ns,semid,semnum,cmd,version,arg);
+               mutex_unlock(&sem_ids(ns).mutex);
                return err;
        default:
                return -EINVAL;
@@ -949,15 +1003,12 @@ static inline void unlock_semundo(void)
 static inline int get_undo_list(struct sem_undo_list **undo_listp)
 {
        struct sem_undo_list *undo_list;
-       int size;
 
        undo_list = current->sysvsem.undo_list;
        if (!undo_list) {
-               size = sizeof(struct sem_undo_list);
-               undo_list = (struct sem_undo_list *) kmalloc(size, GFP_KERNEL);
+               undo_list = kzalloc(sizeof(*undo_list), GFP_KERNEL);
                if (undo_list == NULL)
                        return -ENOMEM;
-               memset(undo_list, 0, size);
                spin_lock_init(&undo_list->lock);
                atomic_set(&undo_list->refcnt, 1);
                current->sysvsem.undo_list = undo_list;
@@ -986,7 +1037,7 @@ static struct sem_undo *lookup_undo(struct sem_undo_list *ulp, int semid)
        return un;
 }
 
-static struct sem_undo *find_undo(int semid)
+static struct sem_undo *find_undo(struct ipc_namespace *ns, int semid)
 {
        struct sem_array *sma;
        struct sem_undo_list *ulp;
@@ -1005,12 +1056,12 @@ static struct sem_undo *find_undo(int semid)
                goto out;
 
        /* no undo structure around - allocate one. */
-       sma = sem_lock(semid);
+       sma = sem_lock(ns, semid);
        un = ERR_PTR(-EINVAL);
        if(sma==NULL)
                goto out;
        un = ERR_PTR(-EIDRM);
-       if (sem_checkid(sma,semid)) {
+       if (sem_checkid(ns,sma,semid)) {
                sem_unlock(sma);
                goto out;
        }
@@ -1070,10 +1121,13 @@ asmlinkage long sys_semtimedop(int semid, struct sembuf __user *tsops,
        int undos = 0, alter = 0, max;
        struct sem_queue queue;
        unsigned long jiffies_left = 0;
+       struct ipc_namespace *ns;
+
+       ns = current->nsproxy->ipc_ns;
 
        if (nsops < 1 || semid < 0)
                return -EINVAL;
-       if (nsops > sc_semopm)
+       if (nsops > ns->sc_semopm)
                return -E2BIG;
        if(nsops > SEMOPM_FAST) {
                sops = kmalloc(sizeof(*sops)*nsops,GFP_KERNEL);
@@ -1109,7 +1163,7 @@ asmlinkage long sys_semtimedop(int semid, struct sembuf __user *tsops,
 
 retry_undos:
        if (undos) {
-               un = find_undo(semid);
+               un = find_undo(ns, semid);
                if (IS_ERR(un)) {
                        error = PTR_ERR(un);
                        goto out_free;
@@ -1117,12 +1171,12 @@ retry_undos:
        } else
                un = NULL;
 
-       sma = sem_lock(semid);
+       sma = sem_lock(ns, semid);
        error=-EINVAL;
        if(sma==NULL)
                goto out_free;
        error = -EIDRM;
-       if (sem_checkid(sma,semid))
+       if (sem_checkid(ns,sma,semid))
                goto out_unlock_free;
        /*
         * semid identifies are not unique - find_undo may have
@@ -1190,7 +1244,7 @@ retry_undos:
                goto out_free;
        }
 
-       sma = sem_lock(semid);
+       sma = sem_lock(ns, semid);
        if(sma==NULL) {
                BUG_ON(queue.prev != NULL);
                error = -EIDRM;
@@ -1267,6 +1321,7 @@ void exit_sem(struct task_struct *tsk)
 {
        struct sem_undo_list *undo_list;
        struct sem_undo *u, **up;
+       struct ipc_namespace *ns;
 
        undo_list = tsk->sysvsem.undo_list;
        if (!undo_list)
@@ -1275,6 +1330,7 @@ void exit_sem(struct task_struct *tsk)
        if (!atomic_dec_and_test(&undo_list->refcnt))
                return;
 
+       ns = tsk->nsproxy->ipc_ns;
        /* There's no need to hold the semundo list lock, as current
          * is the last task exiting for this undo list.
         */
@@ -1288,14 +1344,14 @@ void exit_sem(struct task_struct *tsk)
 
                if(semid == -1)
                        continue;
-               sma = sem_lock(semid);
+               sma = sem_lock(ns, semid);
                if (sma == NULL)
                        continue;
 
                if (u->semid == -1)
                        goto next_entry;
 
-               BUG_ON(sem_checkid(sma,u->semid));
+               BUG_ON(sem_checkid(ns,sma,u->semid));
 
                /* remove u from the sma->undo list */
                for (unp = &sma->undo; (un = *unp); unp = &un->id_next) {
index 940b0c9b13aab7c33159760bba2a3a53756779dd..bfbd317ec11c0be1a73bc85b82d37ee3bbf33dd3 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
  *
  * support for audit of ipc object properties and permission changes
  * Dustin Kirkland <dustin.kirkland@us.ibm.com>
+ *
+ * namespaces support
+ * OpenVZ, SWsoft Inc.
+ * Pavel Emelianov <xemul@openvz.org>
  */
 
 #include <linux/slab.h>
@@ -32,6 +36,7 @@
 #include <linux/ptrace.h>
 #include <linux/seq_file.h>
 #include <linux/mutex.h>
+#include <linux/nsproxy.h>
 
 #include <asm/uaccess.h>
 
 static struct file_operations shm_file_operations;
 static struct vm_operations_struct shm_vm_ops;
 
-static struct ipc_ids shm_ids;
+static struct ipc_ids init_shm_ids;
+
+#define shm_ids(ns)    (*((ns)->ids[IPC_SHM_IDS]))
 
-#define shm_lock(id)   ((struct shmid_kernel*)ipc_lock(&shm_ids,id))
-#define shm_unlock(shp)        ipc_unlock(&(shp)->shm_perm)
-#define shm_get(id)    ((struct shmid_kernel*)ipc_get(&shm_ids,id))
-#define shm_buildid(id, seq) \
-       ipc_buildid(&shm_ids, id, seq)
+#define shm_lock(ns, id)               \
+       ((struct shmid_kernel*)ipc_lock(&shm_ids(ns),id))
+#define shm_unlock(shp)                        \
+       ipc_unlock(&(shp)->shm_perm)
+#define shm_get(ns, id)                        \
+       ((struct shmid_kernel*)ipc_get(&shm_ids(ns),id))
+#define shm_buildid(ns, id, seq)       \
+       ipc_buildid(&shm_ids(ns), id, seq)
 
-static int newseg (key_t key, int shmflg, size_t size);
+static int newseg (struct ipc_namespace *ns, key_t key,
+               int shmflg, size_t size);
 static void shm_open (struct vm_area_struct *shmd);
 static void shm_close (struct vm_area_struct *shmd);
+static void shm_destroy (struct ipc_namespace *ns, struct shmid_kernel *shp);
 #ifdef CONFIG_PROC_FS
 static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
 #endif
 
-size_t shm_ctlmax = SHMMAX;
-size_t         shm_ctlall = SHMALL;
-int    shm_ctlmni = SHMMNI;
+static void __ipc_init __shm_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
+{
+       ns->ids[IPC_SHM_IDS] = ids;
+       ns->shm_ctlmax = SHMMAX;
+       ns->shm_ctlall = SHMALL;
+       ns->shm_ctlmni = SHMMNI;
+       ns->shm_tot = 0;
+       ipc_init_ids(ids, 1);
+}
+
+static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp)
+{
+       if (shp->shm_nattch){
+               shp->shm_perm.mode |= SHM_DEST;
+               /* Do not find it any more */
+               shp->shm_perm.key = IPC_PRIVATE;
+               shm_unlock(shp);
+       } else
+               shm_destroy(ns, shp);
+}
+
+#ifdef CONFIG_IPC_NS
+int shm_init_ns(struct ipc_namespace *ns)
+{
+       struct ipc_ids *ids;
+
+       ids = kmalloc(sizeof(struct ipc_ids), GFP_KERNEL);
+       if (ids == NULL)
+               return -ENOMEM;
 
-static int shm_tot; /* total number of shared memory pages */
+       __shm_init_ns(ns, ids);
+       return 0;
+}
+
+void shm_exit_ns(struct ipc_namespace *ns)
+{
+       int i;
+       struct shmid_kernel *shp;
+
+       mutex_lock(&shm_ids(ns).mutex);
+       for (i = 0; i <= shm_ids(ns).max_id; i++) {
+               shp = shm_lock(ns, i);
+               if (shp == NULL)
+                       continue;
+
+               do_shm_rmid(ns, shp);
+       }
+       mutex_unlock(&shm_ids(ns).mutex);
+
+       kfree(ns->ids[IPC_SHM_IDS]);
+       ns->ids[IPC_SHM_IDS] = NULL;
+}
+#endif
 
 void __init shm_init (void)
 {
-       ipc_init_ids(&shm_ids, 1);
+       __shm_init_ns(&init_ipc_ns, &init_shm_ids);
        ipc_init_proc_interface("sysvipc/shm",
                                "       key      shmid perms       size  cpid  lpid nattch   uid   gid  cuid  cgid      atime      dtime      ctime\n",
-                               &shm_ids,
-                               sysvipc_shm_proc_show);
+                               IPC_SHM_IDS, sysvipc_shm_proc_show);
 }
 
-static inline int shm_checkid(struct shmid_kernel *s, int id)
+static inline int shm_checkid(struct ipc_namespace *ns,
+               struct shmid_kernel *s, int id)
 {
-       if (ipc_checkid(&shm_ids,&s->shm_perm,id))
+       if (ipc_checkid(&shm_ids(ns), &s->shm_perm, id))
                return -EIDRM;
        return 0;
 }
 
-static inline struct shmid_kernel *shm_rmid(int id)
+static inline struct shmid_kernel *shm_rmid(struct ipc_namespace *ns, int id)
 {
-       return (struct shmid_kernel *)ipc_rmid(&shm_ids,id);
+       return (struct shmid_kernel *)ipc_rmid(&shm_ids(ns), id);
 }
 
-static inline int shm_addid(struct shmid_kernel *shp)
+static inline int shm_addid(struct ipc_namespace *ns, struct shmid_kernel *shp)
 {
-       return ipc_addid(&shm_ids, &shp->shm_perm, shm_ctlmni);
+       return ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni);
 }
 
 
 
-static inline void shm_inc (int id) {
+static inline void shm_inc(struct ipc_namespace *ns, int id)
+{
        struct shmid_kernel *shp;
 
-       shp = shm_lock(id);
+       shp = shm_lock(ns, id);
        BUG_ON(!shp);
        shp->shm_atim = get_seconds();
        shp->shm_lprid = current->tgid;
@@ -100,10 +161,13 @@ static inline void shm_inc (int id) {
        shm_unlock(shp);
 }
 
+#define shm_file_ns(file) (*((struct ipc_namespace **)&(file)->private_data))
+
 /* This is called by fork, once for every shm attach. */
-static void shm_open (struct vm_area_struct *shmd)
+static void shm_open(struct vm_area_struct *shmd)
 {
-       shm_inc (shmd->vm_file->f_dentry->d_inode->i_ino);
+       shm_inc(shm_file_ns(shmd->vm_file),
+                       shmd->vm_file->f_dentry->d_inode->i_ino);
 }
 
 /*
@@ -114,10 +178,10 @@ static void shm_open (struct vm_area_struct *shmd)
  * It has to be called with shp and shm_ids.mutex locked,
  * but returns with shp unlocked and freed.
  */
-static void shm_destroy (struct shmid_kernel *shp)
+static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
 {
-       shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
-       shm_rmid (shp->id);
+       ns->shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
+       shm_rmid(ns, shp->id);
        shm_unlock(shp);
        if (!is_file_hugepages(shp->shm_file))
                shmem_lock(shp->shm_file, 0, shp->mlock_user);
@@ -140,20 +204,23 @@ static void shm_close (struct vm_area_struct *shmd)
        struct file * file = shmd->vm_file;
        int id = file->f_dentry->d_inode->i_ino;
        struct shmid_kernel *shp;
+       struct ipc_namespace *ns;
 
-       mutex_lock(&shm_ids.mutex);
+       ns = shm_file_ns(file);
+
+       mutex_lock(&shm_ids(ns).mutex);
        /* remove from the list of attaches of the shm segment */
-       shp = shm_lock(id);
+       shp = shm_lock(ns, id);
        BUG_ON(!shp);
        shp->shm_lprid = current->tgid;
        shp->shm_dtim = get_seconds();
        shp->shm_nattch--;
        if(shp->shm_nattch == 0 &&
           shp->shm_perm.mode & SHM_DEST)
-               shm_destroy (shp);
+               shm_destroy(ns, shp);
        else
                shm_unlock(shp);
-       mutex_unlock(&shm_ids.mutex);
+       mutex_unlock(&shm_ids(ns).mutex);
 }
 
 static int shm_mmap(struct file * file, struct vm_area_struct * vma)
@@ -165,14 +232,25 @@ static int shm_mmap(struct file * file, struct vm_area_struct * vma)
                vma->vm_ops = &shm_vm_ops;
                if (!(vma->vm_flags & VM_WRITE))
                        vma->vm_flags &= ~VM_MAYWRITE;
-               shm_inc(file->f_dentry->d_inode->i_ino);
+               shm_inc(shm_file_ns(file), file->f_dentry->d_inode->i_ino);
        }
 
        return ret;
 }
 
+static int shm_release(struct inode *ino, struct file *file)
+{
+       struct ipc_namespace *ns;
+
+       ns = shm_file_ns(file);
+       put_ipc_ns(ns);
+       shm_file_ns(file) = NULL;
+       return 0;
+}
+
 static struct file_operations shm_file_operations = {
-       .mmap   = shm_mmap,
+       .mmap           = shm_mmap,
+       .release        = shm_release,
 #ifndef CONFIG_MMU
        .get_unmapped_area = shmem_get_unmapped_area,
 #endif
@@ -188,7 +266,7 @@ static struct vm_operations_struct shm_vm_ops = {
 #endif
 };
 
-static int newseg (key_t key, int shmflg, size_t size)
+static int newseg (struct ipc_namespace *ns, key_t key, int shmflg, size_t size)
 {
        int error;
        struct shmid_kernel *shp;
@@ -197,10 +275,10 @@ static int newseg (key_t key, int shmflg, size_t size)
        char name[13];
        int id;
 
-       if (size < SHMMIN || size > shm_ctlmax)
+       if (size < SHMMIN || size > ns->shm_ctlmax)
                return -EINVAL;
 
-       if (shm_tot + numpages >= shm_ctlall)
+       if (ns->shm_tot + numpages >= ns->shm_ctlall)
                return -ENOSPC;
 
        shp = ipc_rcu_alloc(sizeof(*shp));
@@ -239,7 +317,7 @@ static int newseg (key_t key, int shmflg, size_t size)
                goto no_file;
 
        error = -ENOSPC;
-       id = shm_addid(shp);
+       id = shm_addid(ns, shp);
        if(id == -1) 
                goto no_id;
 
@@ -249,15 +327,17 @@ static int newseg (key_t key, int shmflg, size_t size)
        shp->shm_ctim = get_seconds();
        shp->shm_segsz = size;
        shp->shm_nattch = 0;
-       shp->id = shm_buildid(id,shp->shm_perm.seq);
+       shp->id = shm_buildid(ns, id, shp->shm_perm.seq);
        shp->shm_file = file;
        file->f_dentry->d_inode->i_ino = shp->id;
 
+       shm_file_ns(file) = get_ipc_ns(ns);
+
        /* Hugetlb ops would have already been assigned. */
        if (!(shmflg & SHM_HUGETLB))
                file->f_op = &shm_file_operations;
 
-       shm_tot += numpages;
+       ns->shm_tot += numpages;
        shm_unlock(shp);
        return shp->id;
 
@@ -273,33 +353,36 @@ asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
 {
        struct shmid_kernel *shp;
        int err, id = 0;
+       struct ipc_namespace *ns;
+
+       ns = current->nsproxy->ipc_ns;
 
-       mutex_lock(&shm_ids.mutex);
+       mutex_lock(&shm_ids(ns).mutex);
        if (key == IPC_PRIVATE) {
-               err = newseg(key, shmflg, size);
-       } else if ((id = ipc_findkey(&shm_ids, key)) == -1) {
+               err = newseg(ns, key, shmflg, size);
+       } else if ((id = ipc_findkey(&shm_ids(ns), key)) == -1) {
                if (!(shmflg & IPC_CREAT))
                        err = -ENOENT;
                else
-                       err = newseg(key, shmflg, size);
+                       err = newseg(ns, key, shmflg, size);
        } else if ((shmflg & IPC_CREAT) && (shmflg & IPC_EXCL)) {
                err = -EEXIST;
        } else {
-               shp = shm_lock(id);
+               shp = shm_lock(ns, id);
                BUG_ON(shp==NULL);
                if (shp->shm_segsz < size)
                        err = -EINVAL;
                else if (ipcperms(&shp->shm_perm, shmflg))
                        err = -EACCES;
                else {
-                       int shmid = shm_buildid(id, shp->shm_perm.seq);
+                       int shmid = shm_buildid(ns, id, shp->shm_perm.seq);
                        err = security_shm_associate(shp, shmflg);
                        if (!err)
                                err = shmid;
                }
                shm_unlock(shp);
        }
-       mutex_unlock(&shm_ids.mutex);
+       mutex_unlock(&shm_ids(ns).mutex);
 
        return err;
 }
@@ -395,18 +478,19 @@ static inline unsigned long copy_shminfo_to_user(void __user *buf, struct shminf
        }
 }
 
-static void shm_get_stat(unsigned long *rss, unsigned long *swp) 
+static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss,
+               unsigned long *swp)
 {
        int i;
 
        *rss = 0;
        *swp = 0;
 
-       for (i = 0; i <= shm_ids.max_id; i++) {
+       for (i = 0; i <= shm_ids(ns).max_id; i++) {
                struct shmid_kernel *shp;
                struct inode *inode;
 
-               shp = shm_get(i);
+               shp = shm_get(ns, i);
                if(!shp)
                        continue;
 
@@ -430,6 +514,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
        struct shm_setbuf setbuf;
        struct shmid_kernel *shp;
        int err, version;
+       struct ipc_namespace *ns;
 
        if (cmd < 0 || shmid < 0) {
                err = -EINVAL;
@@ -437,6 +522,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
        }
 
        version = ipc_parse_version(&cmd);
+       ns = current->nsproxy->ipc_ns;
 
        switch (cmd) { /* replace with proc interface ? */
        case IPC_INFO:
@@ -448,15 +534,15 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
                        return err;
 
                memset(&shminfo,0,sizeof(shminfo));
-               shminfo.shmmni = shminfo.shmseg = shm_ctlmni;
-               shminfo.shmmax = shm_ctlmax;
-               shminfo.shmall = shm_ctlall;
+               shminfo.shmmni = shminfo.shmseg = ns->shm_ctlmni;
+               shminfo.shmmax = ns->shm_ctlmax;
+               shminfo.shmall = ns->shm_ctlall;
 
                shminfo.shmmin = SHMMIN;
                if(copy_shminfo_to_user (buf, &shminfo, version))
                        return -EFAULT;
                /* reading a integer is always atomic */
-               err= shm_ids.max_id;
+               err= shm_ids(ns).max_id;
                if(err<0)
                        err = 0;
                goto out;
@@ -470,14 +556,14 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
                        return err;
 
                memset(&shm_info,0,sizeof(shm_info));
-               mutex_lock(&shm_ids.mutex);
-               shm_info.used_ids = shm_ids.in_use;
-               shm_get_stat (&shm_info.shm_rss, &shm_info.shm_swp);
-               shm_info.shm_tot = shm_tot;
+               mutex_lock(&shm_ids(ns).mutex);
+               shm_info.used_ids = shm_ids(ns).in_use;
+               shm_get_stat (ns, &shm_info.shm_rss, &shm_info.shm_swp);
+               shm_info.shm_tot = ns->shm_tot;
                shm_info.swap_attempts = 0;
                shm_info.swap_successes = 0;
-               err = shm_ids.max_id;
-               mutex_unlock(&shm_ids.mutex);
+               err = shm_ids(ns).max_id;
+               mutex_unlock(&shm_ids(ns).mutex);
                if(copy_to_user (buf, &shm_info, sizeof(shm_info))) {
                        err = -EFAULT;
                        goto out;
@@ -492,17 +578,17 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
                struct shmid64_ds tbuf;
                int result;
                memset(&tbuf, 0, sizeof(tbuf));
-               shp = shm_lock(shmid);
+               shp = shm_lock(ns, shmid);
                if(shp==NULL) {
                        err = -EINVAL;
                        goto out;
                } else if(cmd==SHM_STAT) {
                        err = -EINVAL;
-                       if (shmid > shm_ids.max_id)
+                       if (shmid > shm_ids(ns).max_id)
                                goto out_unlock;
-                       result = shm_buildid(shmid, shp->shm_perm.seq);
+                       result = shm_buildid(ns, shmid, shp->shm_perm.seq);
                } else {
-                       err = shm_checkid(shp,shmid);
+                       err = shm_checkid(ns, shp,shmid);
                        if(err)
                                goto out_unlock;
                        result = 0;
@@ -534,12 +620,12 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
        case SHM_LOCK:
        case SHM_UNLOCK:
        {
-               shp = shm_lock(shmid);
+               shp = shm_lock(ns, shmid);
                if(shp==NULL) {
                        err = -EINVAL;
                        goto out;
                }
-               err = shm_checkid(shp,shmid);
+               err = shm_checkid(ns, shp,shmid);
                if(err)
                        goto out_unlock;
 
@@ -590,12 +676,12 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
                 *      Instead we set a destroyed flag, and then blow
                 *      the name away when the usage hits zero.
                 */
-               mutex_lock(&shm_ids.mutex);
-               shp = shm_lock(shmid);
+               mutex_lock(&shm_ids(ns).mutex);
+               shp = shm_lock(ns, shmid);
                err = -EINVAL;
                if (shp == NULL) 
                        goto out_up;
-               err = shm_checkid(shp, shmid);
+               err = shm_checkid(ns, shp, shmid);
                if(err)
                        goto out_unlock_up;
 
@@ -614,14 +700,8 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
                if (err)
                        goto out_unlock_up;
 
-               if (shp->shm_nattch){
-                       shp->shm_perm.mode |= SHM_DEST;
-                       /* Do not find it any more */
-                       shp->shm_perm.key = IPC_PRIVATE;
-                       shm_unlock(shp);
-               } else
-                       shm_destroy (shp);
-               mutex_unlock(&shm_ids.mutex);
+               do_shm_rmid(ns, shp);
+               mutex_unlock(&shm_ids(ns).mutex);
                goto out;
        }
 
@@ -631,12 +711,12 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
                        err = -EFAULT;
                        goto out;
                }
-               mutex_lock(&shm_ids.mutex);
-               shp = shm_lock(shmid);
+               mutex_lock(&shm_ids(ns).mutex);
+               shp = shm_lock(ns, shmid);
                err=-EINVAL;
                if(shp==NULL)
                        goto out_up;
-               err = shm_checkid(shp,shmid);
+               err = shm_checkid(ns, shp,shmid);
                if(err)
                        goto out_unlock_up;
                err = audit_ipc_obj(&(shp->shm_perm));
@@ -673,7 +753,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
 out_unlock_up:
        shm_unlock(shp);
 out_up:
-       mutex_unlock(&shm_ids.mutex);
+       mutex_unlock(&shm_ids(ns).mutex);
        goto out;
 out_unlock:
        shm_unlock(shp);
@@ -699,6 +779,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
        unsigned long prot;
        int acc_mode;
        void *user_addr;
+       struct ipc_namespace *ns;
 
        if (shmid < 0) {
                err = -EINVAL;
@@ -737,12 +818,13 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
         * We cannot rely on the fs check since SYSV IPC does have an
         * additional creator id...
         */
-       shp = shm_lock(shmid);
+       ns = current->nsproxy->ipc_ns;
+       shp = shm_lock(ns, shmid);
        if(shp == NULL) {
                err = -EINVAL;
                goto out;
        }
-       err = shm_checkid(shp,shmid);
+       err = shm_checkid(ns, shp,shmid);
        if (err) {
                shm_unlock(shp);
                goto out;
@@ -783,16 +865,16 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
 invalid:
        up_write(&current->mm->mmap_sem);
 
-       mutex_lock(&shm_ids.mutex);
-       shp = shm_lock(shmid);
+       mutex_lock(&shm_ids(ns).mutex);
+       shp = shm_lock(ns, shmid);
        BUG_ON(!shp);
        shp->shm_nattch--;
        if(shp->shm_nattch == 0 &&
           shp->shm_perm.mode & SHM_DEST)
-               shm_destroy (shp);
+               shm_destroy(ns, shp);
        else
                shm_unlock(shp);
-       mutex_unlock(&shm_ids.mutex);
+       mutex_unlock(&shm_ids(ns).mutex);
 
        *raddr = (unsigned long) user_addr;
        err = 0;
index 67b6d178db6e17d95b54e84b75361aec9a0544cc..42479e4eec5935b808a198acd34285dae69f2618 100644 (file)
@@ -12,6 +12,9 @@
  *            Mingming Cao <cmm@us.ibm.com>
  * Mar 2006 - support for audit of ipc object properties
  *            Dustin Kirkland <dustin.kirkland@us.ibm.com>
+ * Jun 2006 - namespaces ssupport
+ *            OpenVZ, SWsoft Inc.
+ *            Pavel Emelianov <xemul@openvz.org>
  */
 
 #include <linux/mm.h>
@@ -29,6 +32,7 @@
 #include <linux/seq_file.h>
 #include <linux/proc_fs.h>
 #include <linux/audit.h>
+#include <linux/nsproxy.h>
 
 #include <asm/unistd.h>
 
 struct ipc_proc_iface {
        const char *path;
        const char *header;
-       struct ipc_ids *ids;
+       int ids;
        int (*show)(struct seq_file *, void *);
 };
 
+struct ipc_namespace init_ipc_ns = {
+       .kref = {
+               .refcount       = ATOMIC_INIT(2),
+       },
+};
+
+#ifdef CONFIG_IPC_NS
+static struct ipc_namespace *clone_ipc_ns(struct ipc_namespace *old_ns)
+{
+       int err;
+       struct ipc_namespace *ns;
+
+       err = -ENOMEM;
+       ns = kmalloc(sizeof(struct ipc_namespace), GFP_KERNEL);
+       if (ns == NULL)
+               goto err_mem;
+
+       err = sem_init_ns(ns);
+       if (err)
+               goto err_sem;
+       err = msg_init_ns(ns);
+       if (err)
+               goto err_msg;
+       err = shm_init_ns(ns);
+       if (err)
+               goto err_shm;
+
+       kref_init(&ns->kref);
+       return ns;
+
+err_shm:
+       msg_exit_ns(ns);
+err_msg:
+       sem_exit_ns(ns);
+err_sem:
+       kfree(ns);
+err_mem:
+       return ERR_PTR(err);
+}
+
+int unshare_ipcs(unsigned long unshare_flags, struct ipc_namespace **new_ipc)
+{
+       struct ipc_namespace *new;
+
+       if (unshare_flags & CLONE_NEWIPC) {
+               if (!capable(CAP_SYS_ADMIN))
+                       return -EPERM;
+
+               new = clone_ipc_ns(current->nsproxy->ipc_ns);
+               if (IS_ERR(new))
+                       return PTR_ERR(new);
+
+               *new_ipc = new;
+       }
+
+       return 0;
+}
+
+int copy_ipcs(unsigned long flags, struct task_struct *tsk)
+{
+       struct ipc_namespace *old_ns = tsk->nsproxy->ipc_ns;
+       struct ipc_namespace *new_ns;
+       int err = 0;
+
+       if (!old_ns)
+               return 0;
+
+       get_ipc_ns(old_ns);
+
+       if (!(flags & CLONE_NEWIPC))
+               return 0;
+
+       if (!capable(CAP_SYS_ADMIN)) {
+               err = -EPERM;
+               goto out;
+       }
+
+       new_ns = clone_ipc_ns(old_ns);
+       if (!new_ns) {
+               err = -ENOMEM;
+               goto out;
+       }
+
+       tsk->nsproxy->ipc_ns = new_ns;
+out:
+       put_ipc_ns(old_ns);
+       return err;
+}
+
+void free_ipc_ns(struct kref *kref)
+{
+       struct ipc_namespace *ns;
+
+       ns = container_of(kref, struct ipc_namespace, kref);
+       sem_exit_ns(ns);
+       msg_exit_ns(ns);
+       shm_exit_ns(ns);
+       kfree(ns);
+}
+#endif
+
 /**
  *     ipc_init        -       initialise IPC subsystem
  *
@@ -67,7 +172,7 @@ __initcall(ipc_init);
  *     array itself. 
  */
  
-void __init ipc_init_ids(struct ipc_ids* ids, int size)
+void __ipc_init ipc_init_ids(struct ipc_ids* ids, int size)
 {
        int i;
 
@@ -110,8 +215,7 @@ static struct file_operations sysvipc_proc_fops;
  *     @show: show routine.
  */
 void __init ipc_init_proc_interface(const char *path, const char *header,
-                                   struct ipc_ids *ids,
-                                   int (*show)(struct seq_file *, void *))
+               int ids, int (*show)(struct seq_file *, void *))
 {
        struct proc_dir_entry *pde;
        struct ipc_proc_iface *iface;
@@ -635,6 +739,9 @@ static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos)
        struct ipc_proc_iface *iface = s->private;
        struct kern_ipc_perm *ipc = it;
        loff_t p;
+       struct ipc_ids *ids;
+
+       ids = current->nsproxy->ipc_ns->ids[iface->ids];
 
        /* If we had an ipc id locked before, unlock it */
        if (ipc && ipc != SEQ_START_TOKEN)
@@ -644,8 +751,8 @@ static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos)
         * p = *pos - 1 (because id 0 starts at position 1)
         *          + 1 (because we increment the position by one)
         */
-       for (p = *pos; p <= iface->ids->max_id; p++) {
-               if ((ipc = ipc_lock(iface->ids, p)) != NULL) {
+       for (p = *pos; p <= ids->max_id; p++) {
+               if ((ipc = ipc_lock(ids, p)) != NULL) {
                        *pos = p + 1;
                        return ipc;
                }
@@ -664,12 +771,15 @@ static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos)
        struct ipc_proc_iface *iface = s->private;
        struct kern_ipc_perm *ipc;
        loff_t p;
+       struct ipc_ids *ids;
+
+       ids = current->nsproxy->ipc_ns->ids[iface->ids];
 
        /*
         * Take the lock - this will be released by the corresponding
         * call to stop().
         */
-       mutex_lock(&iface->ids->mutex);
+       mutex_lock(&ids->mutex);
 
        /* pos < 0 is invalid */
        if (*pos < 0)
@@ -680,8 +790,8 @@ static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos)
                return SEQ_START_TOKEN;
 
        /* Find the (pos-1)th ipc */
-       for (p = *pos - 1; p <= iface->ids->max_id; p++) {
-               if ((ipc = ipc_lock(iface->ids, p)) != NULL) {
+       for (p = *pos - 1; p <= ids->max_id; p++) {
+               if ((ipc = ipc_lock(ids, p)) != NULL) {
                        *pos = p + 1;
                        return ipc;
                }
@@ -693,13 +803,15 @@ static void sysvipc_proc_stop(struct seq_file *s, void *it)
 {
        struct kern_ipc_perm *ipc = it;
        struct ipc_proc_iface *iface = s->private;
+       struct ipc_ids *ids;
 
        /* If we had a locked segment, release it */
        if (ipc && ipc != SEQ_START_TOKEN)
                ipc_unlock(ipc);
 
+       ids = current->nsproxy->ipc_ns->ids[iface->ids];
        /* Release the lock we took in start() */
-       mutex_unlock(&iface->ids->mutex);
+       mutex_unlock(&ids->mutex);
 }
 
 static int sysvipc_proc_show(struct seq_file *s, void *it)
index 0181553d31d85d4c3c9c85e712e3db1d17d63e1a..c8fd6b9d77b5e0bfddcae8b2bbf5f40d6ae4ea03 100644 (file)
@@ -3,6 +3,8 @@
  * Copyright (C) 1999 Christoph Rohland
  *
  * ipc helper functions (c) 1999 Manfred Spraul <manfred@colorfullife.com>
+ * namespaces support.      2006 OpenVZ, SWsoft Inc.
+ *                               Pavel Emelianov <xemul@openvz.org>
  */
 
 #ifndef _IPC_UTIL_H
@@ -15,6 +17,14 @@ void sem_init (void);
 void msg_init (void);
 void shm_init (void);
 
+int sem_init_ns(struct ipc_namespace *ns);
+int msg_init_ns(struct ipc_namespace *ns);
+int shm_init_ns(struct ipc_namespace *ns);
+
+void sem_exit_ns(struct ipc_namespace *ns);
+void msg_exit_ns(struct ipc_namespace *ns);
+void shm_exit_ns(struct ipc_namespace *ns);
+
 struct ipc_id_ary {
        int size;
        struct kern_ipc_perm *p[0];
@@ -31,15 +41,23 @@ struct ipc_ids {
 };
 
 struct seq_file;
-void __init ipc_init_ids(struct ipc_ids* ids, int size);
+#ifdef CONFIG_IPC_NS
+#define __ipc_init
+#else
+#define __ipc_init     __init
+#endif
+void __ipc_init ipc_init_ids(struct ipc_ids *ids, int size);
 #ifdef CONFIG_PROC_FS
 void __init ipc_init_proc_interface(const char *path, const char *header,
-                                   struct ipc_ids *ids,
-                                   int (*show)(struct seq_file *, void *));
+               int ids, int (*show)(struct seq_file *, void *));
 #else
 #define ipc_init_proc_interface(path, header, ids, show) do {} while (0)
 #endif
 
+#define IPC_SEM_IDS    0
+#define IPC_MSG_IDS    1
+#define IPC_SHM_IDS    2
+
 /* must be called with ids->mutex acquired.*/
 int ipc_findkey(struct ipc_ids* ids, key_t key);
 int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size);
index aacaafb28b9d7dca51c09d15af71c119ed51bbf1..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
+           hrtimer.o rwsem.o latency.o nsproxy.o srcu.o
 
 obj-$(CONFIG_STACKTRACE) += stacktrace.o
 obj-y += time/
@@ -48,6 +48,7 @@ obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
 obj-$(CONFIG_SECCOMP) += seccomp.o
 obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
 obj-$(CONFIG_RELAY) += relay.o
+obj-$(CONFIG_UTS_NS) += utsname.o
 obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
 obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o
 
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 b4fbd838cd775ac9007af6e7d566652e1ad629de..75573e5d27b05c92dd1a11aaf483415935032624 100644 (file)
@@ -26,8 +26,6 @@
 
 #include <asm/uaccess.h>
 
-extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
-
 int get_compat_timespec(struct timespec *ts, const struct compat_timespec __user *cts)
 {
        return (!access_ok(VERIFY_READ, cts, sizeof(*cts)) ||
index aef0a45b7893db2c7a5a2c94f67da7618e181bc9..2020644c938a48d0f34670765e788b32fed8900d 100644 (file)
@@ -62,6 +62,11 @@ static struct dma_chan dma_chan_busy[MAX_DMA_CHANNELS] = {
 };
 
 
+/**
+ * request_dma - request and reserve a system DMA channel
+ * @dmanr: DMA channel number
+ * @device_id: reserving device ID string, used in /proc/dma
+ */
 int request_dma(unsigned int dmanr, const char * device_id)
 {
        if (dmanr >= MAX_DMA_CHANNELS)
@@ -76,7 +81,10 @@ int request_dma(unsigned int dmanr, const char * device_id)
        return 0;
 } /* request_dma */
 
-
+/**
+ * free_dma - free a reserved system DMA channel
+ * @dmanr: DMA channel number
+ */
 void free_dma(unsigned int dmanr)
 {
        if (dmanr >= MAX_DMA_CHANNELS) {
index 3b47f26985f2bed8a2895a3974ff413c086409f5..f250a5e3e28151d293741a6604938d49c9336feb 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/tsacct_kern.h>
 #include <linux/file.h>
 #include <linux/binfmts.h>
+#include <linux/nsproxy.h>
 #include <linux/ptrace.h>
 #include <linux/profile.h>
 #include <linux/mount.h>
@@ -397,9 +398,11 @@ void daemonize(const char *name, ...)
        fs = init_task.fs;
        current->fs = fs;
        atomic_inc(&fs->count);
-       exit_namespace(current);
-       current->namespace = init_task.namespace;
-       get_namespace(current->namespace);
+
+       exit_task_namespaces(current);
+       current->nsproxy = init_task.nsproxy;
+       get_task_namespaces(current);
+
        exit_files(current);
        current->files = init_task.files;
        atomic_inc(&current->files->count);
@@ -917,7 +920,6 @@ fastcall NORET_TYPE void do_exit(long code)
        exit_sem(tsk);
        __exit_files(tsk);
        __exit_fs(tsk);
-       exit_namespace(tsk);
        exit_thread();
        cpuset_exit(tsk);
        exit_keys(tsk);
@@ -932,6 +934,7 @@ fastcall NORET_TYPE void do_exit(long code)
        tsk->exit_code = code;
        proc_exit_connector(tsk);
        exit_notify(tsk);
+       exit_task_namespaces(tsk);
 #ifdef CONFIG_NUMA
        mpol_free(tsk->mempolicy);
        tsk->mempolicy = NULL;
index 89f666491d1f91d2ff2c7f4090003465299bcb6a..7dc6140baac69325f1ce2fa08fa9bd858aa57258 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/binfmts.h>
 #include <linux/mman.h>
 #include <linux/fs.h>
+#include <linux/nsproxy.h>
 #include <linux/capability.h>
 #include <linux/cpu.h>
 #include <linux/cpuset.h>
@@ -1116,11 +1117,11 @@ static struct task_struct *copy_process(unsigned long clone_flags,
                goto bad_fork_cleanup_signal;
        if ((retval = copy_keys(clone_flags, p)))
                goto bad_fork_cleanup_mm;
-       if ((retval = copy_namespace(clone_flags, p)))
+       if ((retval = copy_namespaces(clone_flags, p)))
                goto bad_fork_cleanup_keys;
        retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
        if (retval)
-               goto bad_fork_cleanup_namespace;
+               goto bad_fork_cleanup_namespaces;
 
        p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
        /*
@@ -1212,7 +1213,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
                spin_unlock(&current->sighand->siglock);
                write_unlock_irq(&tasklist_lock);
                retval = -ERESTARTNOINTR;
-               goto bad_fork_cleanup_namespace;
+               goto bad_fork_cleanup_namespaces;
        }
 
        if (clone_flags & CLONE_THREAD) {
@@ -1260,8 +1261,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        proc_fork_connector(p);
        return p;
 
-bad_fork_cleanup_namespace:
-       exit_namespace(p);
+bad_fork_cleanup_namespaces:
+       exit_task_namespaces(p);
 bad_fork_cleanup_keys:
        exit_keys(p);
 bad_fork_cleanup_mm:
@@ -1514,10 +1515,9 @@ static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)
  */
 static int unshare_namespace(unsigned long unshare_flags, struct namespace **new_nsp, struct fs_struct *new_fs)
 {
-       struct namespace *ns = current->namespace;
+       struct namespace *ns = current->nsproxy->namespace;
 
-       if ((unshare_flags & CLONE_NEWNS) &&
-           (ns && atomic_read(&ns->count) > 1)) {
+       if ((unshare_flags & CLONE_NEWNS) && ns) {
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
 
@@ -1589,6 +1589,16 @@ static int unshare_semundo(unsigned long unshare_flags, struct sem_undo_list **n
        return 0;
 }
 
+#ifndef CONFIG_IPC_NS
+static inline int unshare_ipcs(unsigned long flags, struct ipc_namespace **ns)
+{
+       if (flags & CLONE_NEWIPC)
+               return -EINVAL;
+
+       return 0;
+}
+#endif
+
 /*
  * unshare allows a process to 'unshare' part of the process
  * context which was originally shared using clone.  copy_*
@@ -1606,13 +1616,17 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
        struct mm_struct *mm, *new_mm = NULL, *active_mm = NULL;
        struct files_struct *fd, *new_fd = NULL;
        struct sem_undo_list *new_ulist = NULL;
+       struct nsproxy *new_nsproxy = NULL, *old_nsproxy = NULL;
+       struct uts_namespace *uts, *new_uts = NULL;
+       struct ipc_namespace *ipc, *new_ipc = NULL;
 
        check_unshare_flags(&unshare_flags);
 
        /* Return -EINVAL for all unsupported flags */
        err = -EINVAL;
        if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND|
-                               CLONE_VM|CLONE_FILES|CLONE_SYSVSEM))
+                               CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|
+                               CLONE_NEWUTS|CLONE_NEWIPC))
                goto bad_unshare_out;
 
        if ((err = unshare_thread(unshare_flags)))
@@ -1629,11 +1643,30 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
                goto bad_unshare_cleanup_vm;
        if ((err = unshare_semundo(unshare_flags, &new_ulist)))
                goto bad_unshare_cleanup_fd;
+       if ((err = unshare_utsname(unshare_flags, &new_uts)))
+               goto bad_unshare_cleanup_semundo;
+       if ((err = unshare_ipcs(unshare_flags, &new_ipc)))
+               goto bad_unshare_cleanup_uts;
+
+       if (new_ns || new_uts || new_ipc) {
+               old_nsproxy = current->nsproxy;
+               new_nsproxy = dup_namespaces(old_nsproxy);
+               if (!new_nsproxy) {
+                       err = -ENOMEM;
+                       goto bad_unshare_cleanup_ipc;
+               }
+       }
 
-       if (new_fs || new_ns || new_sigh || new_mm || new_fd || new_ulist) {
+       if (new_fs || new_ns || new_sigh || new_mm || new_fd || new_ulist ||
+                               new_uts || new_ipc) {
 
                task_lock(current);
 
+               if (new_nsproxy) {
+                       current->nsproxy = new_nsproxy;
+                       new_nsproxy = old_nsproxy;
+               }
+
                if (new_fs) {
                        fs = current->fs;
                        current->fs = new_fs;
@@ -1641,8 +1674,8 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
                }
 
                if (new_ns) {
-                       ns = current->namespace;
-                       current->namespace = new_ns;
+                       ns = current->nsproxy->namespace;
+                       current->nsproxy->namespace = new_ns;
                        new_ns = ns;
                }
 
@@ -1667,9 +1700,33 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
                        new_fd = fd;
                }
 
+               if (new_uts) {
+                       uts = current->nsproxy->uts_ns;
+                       current->nsproxy->uts_ns = new_uts;
+                       new_uts = uts;
+               }
+
+               if (new_ipc) {
+                       ipc = current->nsproxy->ipc_ns;
+                       current->nsproxy->ipc_ns = new_ipc;
+                       new_ipc = ipc;
+               }
+
                task_unlock(current);
        }
 
+       if (new_nsproxy)
+               put_nsproxy(new_nsproxy);
+
+bad_unshare_cleanup_ipc:
+       if (new_ipc)
+               put_ipc_ns(new_ipc);
+
+bad_unshare_cleanup_uts:
+       if (new_uts)
+               put_uts_ns(new_uts);
+
+bad_unshare_cleanup_semundo:
 bad_unshare_cleanup_fd:
        if (new_fd)
                put_files_struct(new_fd);
index 4b6770e9806d0c080ef5f9bd542ddb778ddbcff2..4aaf91951a43959be9d448b66fe7538d46f7d244 100644 (file)
@@ -1527,7 +1527,7 @@ static int futex_fd(u32 __user *uaddr, int signal)
        filp->f_mapping = filp->f_dentry->d_inode->i_mapping;
 
        if (signal) {
-               err = f_setown(filp, current->pid, 1);
+               err = __f_setown(filp, task_pid(current), PIDTYPE_PID, 1);
                if (err < 0) {
                        goto error;
                }
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 ab16a5a4cfe9ba4c1e3009f136e4c6d11a8cffa7..eeac3e313b2bfa41f26a4ccd9235232593fb947c 100644 (file)
@@ -69,6 +69,15 @@ static inline int is_kernel(unsigned long addr)
        return in_gate_area_no_task(addr);
 }
 
+static int is_ksym_addr(unsigned long addr)
+{
+       if (all_var)
+               return is_kernel(addr);
+
+       return is_kernel_text(addr) || is_kernel_inittext(addr) ||
+               is_kernel_extratext(addr);
+}
+
 /* expand a compressed symbol data into the resulting uncompressed string,
    given the offset to where the symbol is in the compressed stream */
 static unsigned int kallsyms_expand_symbol(unsigned int off, char *result)
@@ -154,7 +163,73 @@ unsigned long kallsyms_lookup_name(const char *name)
        }
        return module_kallsyms_lookup_name(name);
 }
-EXPORT_SYMBOL_GPL(kallsyms_lookup_name);
+
+static unsigned long get_symbol_pos(unsigned long addr,
+                                   unsigned long *symbolsize,
+                                   unsigned long *offset)
+{
+       unsigned long symbol_start = 0, symbol_end = 0;
+       unsigned long i, low, high, mid;
+
+       /* This kernel should never had been booted. */
+       BUG_ON(!kallsyms_addresses);
+
+       /* do a binary search on the sorted kallsyms_addresses array */
+       low = 0;
+       high = kallsyms_num_syms;
+
+       while (high - low > 1) {
+               mid = (low + high) / 2;
+               if (kallsyms_addresses[mid] <= addr)
+                       low = mid;
+               else
+                       high = mid;
+       }
+
+       /*
+        * search for the first aliased symbol. Aliased
+        * symbols are symbols with the same address
+        */
+       while (low && kallsyms_addresses[low-1] == kallsyms_addresses[low])
+               --low;
+
+       symbol_start = kallsyms_addresses[low];
+
+       /* Search for next non-aliased symbol */
+       for (i = low + 1; i < kallsyms_num_syms; i++) {
+               if (kallsyms_addresses[i] > symbol_start) {
+                       symbol_end = kallsyms_addresses[i];
+                       break;
+               }
+       }
+
+       /* if we found no next symbol, we use the end of the section */
+       if (!symbol_end) {
+               if (is_kernel_inittext(addr))
+                       symbol_end = (unsigned long)_einittext;
+               else if (all_var)
+                       symbol_end = (unsigned long)_end;
+               else
+                       symbol_end = (unsigned long)_etext;
+       }
+
+       *symbolsize = symbol_end - symbol_start;
+       *offset = addr - symbol_start;
+
+       return low;
+}
+
+/*
+ * Lookup an address but don't bother to find any names.
+ */
+int kallsyms_lookup_size_offset(unsigned long addr, unsigned long *symbolsize,
+                               unsigned long *offset)
+{
+       if (is_ksym_addr(addr))
+               return !!get_symbol_pos(addr, symbolsize, offset);
+
+       return !!module_address_lookup(addr, symbolsize, offset, NULL);
+}
 
 /*
  * Lookup an address
@@ -168,57 +243,18 @@ const char *kallsyms_lookup(unsigned long addr,
                            unsigned long *offset,
                            char **modname, char *namebuf)
 {
-       unsigned long i, low, high, mid;
        const char *msym;
 
-       /* This kernel should never had been booted. */
-       BUG_ON(!kallsyms_addresses);
-
        namebuf[KSYM_NAME_LEN] = 0;
        namebuf[0] = 0;
 
-       if ((all_var && is_kernel(addr)) ||
-           (!all_var && (is_kernel_text(addr) || is_kernel_inittext(addr) ||
-                               is_kernel_extratext(addr)))) {
-               unsigned long symbol_end = 0;
-
-               /* do a binary search on the sorted kallsyms_addresses array */
-               low = 0;
-               high = kallsyms_num_syms;
-
-               while (high-low > 1) {
-                       mid = (low + high) / 2;
-                       if (kallsyms_addresses[mid] <= addr) low = mid;
-                       else high = mid;
-               }
-
-               /* search for the first aliased symbol. Aliased symbols are
-                  symbols with the same address */
-               while (low && kallsyms_addresses[low - 1] == kallsyms_addresses[low])
-                       --low;
+       if (is_ksym_addr(addr)) {
+               unsigned long pos;
 
+               pos = get_symbol_pos(addr, symbolsize, offset);
                /* Grab name */
-               kallsyms_expand_symbol(get_symbol_offset(low), namebuf);
-
-               /* Search for next non-aliased symbol */
-               for (i = low + 1; i < kallsyms_num_syms; i++) {
-                       if (kallsyms_addresses[i] > kallsyms_addresses[low]) {
-                               symbol_end = kallsyms_addresses[i];
-                               break;
-                       }
-               }
-
-               /* if we found no next symbol, we use the end of the section */
-               if (!symbol_end) {
-                       if (is_kernel_inittext(addr))
-                               symbol_end = (unsigned long)_einittext;
-                       else
-                               symbol_end = all_var ? (unsigned long)_end : (unsigned long)_etext;
-               }
-
-               *symbolsize = symbol_end - kallsyms_addresses[low];
+               kallsyms_expand_symbol(get_symbol_offset(pos), namebuf);
                *modname = NULL;
-               *offset = addr - kallsyms_addresses[low];
                return namebuf;
        }
 
index f8121b95183f3c58502e1cacf6b25c1285ebecc3..bb4e29d924e4ff29567a962e7b643e0c1c875896 100644 (file)
@@ -18,8 +18,6 @@
        call_usermodehelper wait flag, and remove exec_usermodehelper.
        Rusty Russell <rusty@rustcorp.com.au>  Jan 2003
 */
-#define __KERNEL_SYSCALLS__
-
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/syscalls.h>
@@ -169,7 +167,8 @@ static int ____call_usermodehelper(void *data)
 
        retval = -EPERM;
        if (current->fs->root)
-               retval = execve(sub_info->path, sub_info->argv, sub_info->envp);
+               retval = kernel_execve(sub_info->path,
+                               sub_info->argv, sub_info->envp);
 
        /* Exec failed? */
        sub_info->retval = retval;
index 3f57dfdc8f92ba2d60e0b49af23ce6823d0598f1..610c837ad9e0aa8923f48541aaa7ea903c6b2fd2 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/moduleloader.h>
+#include <linux/kallsyms.h>
 #include <asm-generic/sections.h>
 #include <asm/cacheflush.h>
 #include <asm/errno.h>
 #define KPROBE_HASH_BITS 6
 #define KPROBE_TABLE_SIZE (1 << KPROBE_HASH_BITS)
 
+
+/*
+ * Some oddball architectures like 64bit powerpc have function descriptors
+ * so this must be overridable.
+ */
+#ifndef kprobe_lookup_name
+#define kprobe_lookup_name(name, addr) \
+       addr = ((kprobe_opcode_t *)(kallsyms_lookup_name(name)))
+#endif
+
 static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
 static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
 static atomic_t kprobe_count;
@@ -308,7 +319,8 @@ void __kprobes add_rp_inst(struct kretprobe_instance *ri)
 }
 
 /* Called with kretprobe_lock held */
-void __kprobes recycle_rp_inst(struct kretprobe_instance *ri)
+void __kprobes recycle_rp_inst(struct kretprobe_instance *ri,
+                               struct hlist_head *head)
 {
        /* remove rp inst off the rprobe_inst_table */
        hlist_del(&ri->hlist);
@@ -320,7 +332,7 @@ void __kprobes recycle_rp_inst(struct kretprobe_instance *ri)
                hlist_add_head(&ri->uflist, &ri->rp->free_instances);
        } else
                /* Unregistering */
-               kfree(ri);
+               hlist_add_head(&ri->hlist, head);
 }
 
 struct hlist_head __kprobes *kretprobe_inst_table_head(struct task_struct *tsk)
@@ -336,18 +348,24 @@ struct hlist_head __kprobes *kretprobe_inst_table_head(struct task_struct *tsk)
  */
 void __kprobes kprobe_flush_task(struct task_struct *tk)
 {
-        struct kretprobe_instance *ri;
-        struct hlist_head *head;
+       struct kretprobe_instance *ri;
+       struct hlist_head *head, empty_rp;
        struct hlist_node *node, *tmp;
        unsigned long flags = 0;
 
+       INIT_HLIST_HEAD(&empty_rp);
        spin_lock_irqsave(&kretprobe_lock, flags);
-        head = kretprobe_inst_table_head(tk);
-        hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
-                if (ri->task == tk)
-                        recycle_rp_inst(ri);
-        }
+       head = kretprobe_inst_table_head(tk);
+       hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
+               if (ri->task == tk)
+                       recycle_rp_inst(ri, &empty_rp);
+       }
        spin_unlock_irqrestore(&kretprobe_lock, flags);
+
+       hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
+               hlist_del(&ri->hlist);
+               kfree(ri);
+       }
 }
 
 static inline void free_rp_inst(struct kretprobe *rp)
@@ -447,6 +465,21 @@ static int __kprobes __register_kprobe(struct kprobe *p,
        struct kprobe *old_p;
        struct module *probed_mod;
 
+       /*
+        * If we have a symbol_name argument look it up,
+        * and add it to the address.  That way the addr
+        * field can either be global or relative to a symbol.
+        */
+       if (p->symbol_name) {
+               if (p->addr)
+                       return -EINVAL;
+               kprobe_lookup_name(p->symbol_name, p->addr);
+       }
+
+       if (!p->addr)
+               return -EINVAL;
+       p->addr = (kprobe_opcode_t *)(((char *)p->addr)+ p->offset);
+
        if ((!kernel_text_address((unsigned long) p->addr)) ||
                in_kprobes_functions((unsigned long) p->addr))
                return -EINVAL;
@@ -488,7 +521,7 @@ static int __kprobes __register_kprobe(struct kprobe *p,
                                (ARCH_INACTIVE_KPROBE_COUNT + 1))
                register_page_fault_notifier(&kprobe_page_fault_nb);
 
-       arch_arm_kprobe(p);
+       arch_arm_kprobe(p);
 
 out:
        mutex_unlock(&kprobe_mutex);
index e596525669ed4fa5018ee452c7bc429b945f8d00..4c0553461000360e4f4cb459bde0d289f9f89b97 100644 (file)
@@ -518,9 +518,9 @@ print_circular_bug_entry(struct lock_list *target, unsigned int depth)
 
 static void print_kernel_version(void)
 {
-       printk("%s %.*s\n", system_utsname.release,
-               (int)strcspn(system_utsname.version, " "),
-               system_utsname.version);
+       printk("%s %.*s\n", init_utsname()->release,
+               (int)strcspn(init_utsname()->version, " "),
+               init_utsname()->version);
 }
 
 /*
index 05625d5dc7583ac5567d3deec22ebd95c57b72bc..7f60e782de1e49fdfbcc96374e39898920cea94a 100644 (file)
@@ -851,6 +851,7 @@ static int check_version(Elf_Shdr *sechdrs,
                printk("%s: no version for \"%s\" found: kernel tainted.\n",
                       mod->name, symname);
                add_taint(TAINT_FORCED_MODULE);
+               mod->taints |= TAINT_FORCED_MODULE;
        }
        return 1;
 }
@@ -1339,6 +1340,7 @@ static void set_license(struct module *mod, const char *license)
                printk(KERN_WARNING "%s: module license '%s' taints kernel.\n",
                       mod->name, license);
                add_taint(TAINT_PROPRIETARY_MODULE);
+               mod->taints |= TAINT_PROPRIETARY_MODULE;
        }
 }
 
@@ -1618,6 +1620,7 @@ static struct module *load_module(void __user *umod,
        /* This is allowed: modprobe --force will invalidate it. */
        if (!modmagic) {
                add_taint(TAINT_FORCED_MODULE);
+               mod->taints |= TAINT_FORCED_MODULE;
                printk(KERN_WARNING "%s: no version magic, tainting kernel.\n",
                       mod->name);
        } else if (!same_magic(modmagic, vermagic)) {
@@ -1711,10 +1714,14 @@ static struct module *load_module(void __user *umod,
        /* Set up license info based on the info section */
        set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
 
-       if (strcmp(mod->name, "ndiswrapper") == 0)
+       if (strcmp(mod->name, "ndiswrapper") == 0) {
                add_taint(TAINT_PROPRIETARY_MODULE);
-       if (strcmp(mod->name, "driverloader") == 0)
+               mod->taints |= TAINT_PROPRIETARY_MODULE;
+       }
+       if (strcmp(mod->name, "driverloader") == 0) {
                add_taint(TAINT_PROPRIETARY_MODULE);
+               mod->taints |= TAINT_PROPRIETARY_MODULE;
+       }
 
        /* Set up MODINFO_ATTR fields */
        setup_modinfo(mod, sechdrs, infoindex);
@@ -1760,6 +1767,7 @@ static struct module *load_module(void __user *umod,
                printk(KERN_WARNING "%s: No versions for exported symbols."
                       " Tainting kernel.\n", mod->name);
                add_taint(TAINT_FORCED_MODULE);
+               mod->taints |= TAINT_FORCED_MODULE;
        }
 #endif
 
@@ -2032,7 +2040,8 @@ const char *module_address_lookup(unsigned long addr,
        list_for_each_entry(mod, &modules, list) {
                if (within(addr, mod->module_init, mod->init_size)
                    || within(addr, mod->module_core, mod->core_size)) {
-                       *modname = mod->name;
+                       if (modname)
+                               *modname = mod->name;
                        return get_ksymbol(mod, addr, size, offset);
                }
        }
@@ -2226,14 +2235,37 @@ struct module *module_text_address(unsigned long addr)
        return mod;
 }
 
+static char *taint_flags(unsigned int taints, char *buf)
+{
+       *buf = '\0';
+       if (taints) {
+               int bx;
+
+               buf[0] = '(';
+               bx = 1;
+               if (taints & TAINT_PROPRIETARY_MODULE)
+                       buf[bx++] = 'P';
+               if (taints & TAINT_FORCED_MODULE)
+                       buf[bx++] = 'F';
+               /*
+                * TAINT_FORCED_RMMOD: could be added.
+                * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
+                * apply to modules.
+                */
+               buf[bx] = ')';
+       }
+       return buf;
+}
+
 /* Don't grab lock, we're oopsing. */
 void print_modules(void)
 {
        struct module *mod;
+       char buf[8];
 
        printk("Modules linked in:");
        list_for_each_entry(mod, &modules, list)
-               printk(" %s", mod->name);
+               printk(" %s%s", mod->name, taint_flags(mod->taints, buf));
        printk("\n");
 }
 
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
new file mode 100644 (file)
index 0000000..6ebdb82
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ *  Copyright (C) 2006 IBM Corporation
+ *
+ *  Author: Serge Hallyn <serue@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, version 2 of the
+ *  License.
+ *
+ *  Jun 2006 - namespaces support
+ *             OpenVZ, SWsoft Inc.
+ *             Pavel Emelianov <xemul@openvz.org>
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/nsproxy.h>
+#include <linux/init_task.h>
+#include <linux/namespace.h>
+#include <linux/utsname.h>
+
+struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy);
+
+static inline void get_nsproxy(struct nsproxy *ns)
+{
+       atomic_inc(&ns->count);
+}
+
+void get_task_namespaces(struct task_struct *tsk)
+{
+       struct nsproxy *ns = tsk->nsproxy;
+       if (ns) {
+               get_nsproxy(ns);
+       }
+}
+
+/*
+ * creates a copy of "orig" with refcount 1.
+ * This does not grab references to the contained namespaces,
+ * so that needs to be done by dup_namespaces.
+ */
+static inline struct nsproxy *clone_namespaces(struct nsproxy *orig)
+{
+       struct nsproxy *ns;
+
+       ns = kmalloc(sizeof(struct nsproxy), GFP_KERNEL);
+       if (ns) {
+               memcpy(ns, orig, sizeof(struct nsproxy));
+               atomic_set(&ns->count, 1);
+       }
+       return ns;
+}
+
+/*
+ * copies the nsproxy, setting refcount to 1, and grabbing a
+ * reference to all contained namespaces.  Called from
+ * sys_unshare()
+ */
+struct nsproxy *dup_namespaces(struct nsproxy *orig)
+{
+       struct nsproxy *ns = clone_namespaces(orig);
+
+       if (ns) {
+               if (ns->namespace)
+                       get_namespace(ns->namespace);
+               if (ns->uts_ns)
+                       get_uts_ns(ns->uts_ns);
+               if (ns->ipc_ns)
+                       get_ipc_ns(ns->ipc_ns);
+       }
+
+       return ns;
+}
+
+/*
+ * called from clone.  This now handles copy for nsproxy and all
+ * namespaces therein.
+ */
+int copy_namespaces(int flags, struct task_struct *tsk)
+{
+       struct nsproxy *old_ns = tsk->nsproxy;
+       struct nsproxy *new_ns;
+       int err = 0;
+
+       if (!old_ns)
+               return 0;
+
+       get_nsproxy(old_ns);
+
+       if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC)))
+               return 0;
+
+       new_ns = clone_namespaces(old_ns);
+       if (!new_ns) {
+               err = -ENOMEM;
+               goto out;
+       }
+
+       tsk->nsproxy = new_ns;
+
+       err = copy_namespace(flags, tsk);
+       if (err)
+               goto out_ns;
+
+       err = copy_utsname(flags, tsk);
+       if (err)
+               goto out_uts;
+
+       err = copy_ipcs(flags, tsk);
+       if (err)
+               goto out_ipc;
+
+out:
+       put_nsproxy(old_ns);
+       return err;
+
+out_ipc:
+       if (new_ns->uts_ns)
+               put_uts_ns(new_ns->uts_ns);
+out_uts:
+       if (new_ns->namespace)
+               put_namespace(new_ns->namespace);
+out_ns:
+       tsk->nsproxy = old_ns;
+       kfree(new_ns);
+       goto out;
+}
+
+void free_nsproxy(struct nsproxy *ns)
+{
+               if (ns->namespace)
+                       put_namespace(ns->namespace);
+               if (ns->uts_ns)
+                       put_uts_ns(ns->uts_ns);
+               if (ns->ipc_ns)
+                       put_ipc_ns(ns->ipc_ns);
+               kfree(ns);
+}
index 8387e8c681938a968ae005f52c58fcdf11ab17c3..b914392085f9a171f08a3e202dc14145e1563929 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <linux/hash.h>
+#include <linux/pspace.h>
 
 #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
 static struct hlist_head *pid_hash;
@@ -33,17 +34,20 @@ static int pidhash_shift;
 static kmem_cache_t *pid_cachep;
 
 int pid_max = PID_MAX_DEFAULT;
-int last_pid;
 
 #define RESERVED_PIDS          300
 
 int pid_max_min = RESERVED_PIDS + 1;
 int pid_max_max = PID_MAX_LIMIT;
 
-#define PIDMAP_ENTRIES         ((PID_MAX_LIMIT + 8*PAGE_SIZE - 1)/PAGE_SIZE/8)
 #define BITS_PER_PAGE          (PAGE_SIZE*8)
 #define BITS_PER_PAGE_MASK     (BITS_PER_PAGE-1)
-#define mk_pid(map, off)       (((map) - pidmap_array)*BITS_PER_PAGE + (off))
+
+static inline int mk_pid(struct pspace *pspace, struct pidmap *map, int off)
+{
+       return (map - pspace->pidmap)*BITS_PER_PAGE + off;
+}
+
 #define find_next_offset(map, off)                                     \
                find_next_zero_bit((map)->page, BITS_PER_PAGE, off)
 
@@ -53,13 +57,12 @@ int pid_max_max = PID_MAX_LIMIT;
  * value does not cause lots of bitmaps to be allocated, but
  * the scheme scales to up to 4 million PIDs, runtime.
  */
-typedef struct pidmap {
-       atomic_t nr_free;
-       void *page;
-} pidmap_t;
-
-static pidmap_t pidmap_array[PIDMAP_ENTRIES] =
-        { [ 0 ... PIDMAP_ENTRIES-1 ] = { ATOMIC_INIT(BITS_PER_PAGE), NULL } };
+struct pspace init_pspace = {
+       .pidmap = {
+               [ 0 ... PIDMAP_ENTRIES-1] = { ATOMIC_INIT(BITS_PER_PAGE), NULL }
+       },
+       .last_pid = 0
+};
 
 /*
  * Note: disable interrupts while the pidmap_lock is held as an
@@ -74,40 +77,41 @@ static pidmap_t pidmap_array[PIDMAP_ENTRIES] =
  * irq handlers that take it we can leave the interrupts enabled.
  * For now it is easier to be safe than to prove it can't happen.
  */
+
 static  __cacheline_aligned_in_smp DEFINE_SPINLOCK(pidmap_lock);
 
-static fastcall void free_pidmap(int pid)
+static fastcall void free_pidmap(struct pspace *pspace, int pid)
 {
-       pidmap_t *map = pidmap_array + pid / BITS_PER_PAGE;
+       struct pidmap *map = pspace->pidmap + pid / BITS_PER_PAGE;
        int offset = pid & BITS_PER_PAGE_MASK;
 
        clear_bit(offset, map->page);
        atomic_inc(&map->nr_free);
 }
 
-static int alloc_pidmap(void)
+static int alloc_pidmap(struct pspace *pspace)
 {
-       int i, offset, max_scan, pid, last = last_pid;
-       pidmap_t *map;
+       int i, offset, max_scan, pid, last = pspace->last_pid;
+       struct pidmap *map;
 
        pid = last + 1;
        if (pid >= pid_max)
                pid = RESERVED_PIDS;
        offset = pid & BITS_PER_PAGE_MASK;
-       map = &pidmap_array[pid/BITS_PER_PAGE];
+       map = &pspace->pidmap[pid/BITS_PER_PAGE];
        max_scan = (pid_max + BITS_PER_PAGE - 1)/BITS_PER_PAGE - !offset;
        for (i = 0; i <= max_scan; ++i) {
                if (unlikely(!map->page)) {
-                       unsigned long page = get_zeroed_page(GFP_KERNEL);
+                       void *page = kzalloc(PAGE_SIZE, GFP_KERNEL);
                        /*
                         * Free the page if someone raced with us
                         * installing it:
                         */
                        spin_lock_irq(&pidmap_lock);
                        if (map->page)
-                               free_page(page);
+                               kfree(page);
                        else
-                               map->page = (void *)page;
+                               map->page = page;
                        spin_unlock_irq(&pidmap_lock);
                        if (unlikely(!map->page))
                                break;
@@ -116,11 +120,11 @@ static int alloc_pidmap(void)
                        do {
                                if (!test_and_set_bit(offset, map->page)) {
                                        atomic_dec(&map->nr_free);
-                                       last_pid = pid;
+                                       pspace->last_pid = pid;
                                        return pid;
                                }
                                offset = find_next_offset(map, offset);
-                               pid = mk_pid(map, offset);
+                               pid = mk_pid(pspace, map, offset);
                        /*
                         * find_next_offset() found a bit, the pid from it
                         * is in-bounds, and if we fell back to the last
@@ -131,16 +135,34 @@ static int alloc_pidmap(void)
                                        (i != max_scan || pid < last ||
                                            !((last+1) & BITS_PER_PAGE_MASK)));
                }
-               if (map < &pidmap_array[(pid_max-1)/BITS_PER_PAGE]) {
+               if (map < &pspace->pidmap[(pid_max-1)/BITS_PER_PAGE]) {
                        ++map;
                        offset = 0;
                } else {
-                       map = &pidmap_array[0];
+                       map = &pspace->pidmap[0];
                        offset = RESERVED_PIDS;
                        if (unlikely(last == offset))
                                break;
                }
-               pid = mk_pid(map, offset);
+               pid = mk_pid(pspace, map, offset);
+       }
+       return -1;
+}
+
+static int next_pidmap(struct pspace *pspace, int last)
+{
+       int offset;
+       struct pidmap *map, *end;
+
+       offset = (last + 1) & BITS_PER_PAGE_MASK;
+       map = &pspace->pidmap[(last + 1)/BITS_PER_PAGE];
+       end = &pspace->pidmap[PIDMAP_ENTRIES];
+       for (; map < end; map++, offset = 0) {
+               if (unlikely(!map->page))
+                       continue;
+               offset = find_next_bit((map)->page, BITS_PER_PAGE, offset);
+               if (offset < BITS_PER_PAGE)
+                       return mk_pid(pspace, map, offset);
        }
        return -1;
 }
@@ -153,6 +175,7 @@ fastcall void put_pid(struct pid *pid)
             atomic_dec_and_test(&pid->count))
                kmem_cache_free(pid_cachep, pid);
 }
+EXPORT_SYMBOL_GPL(put_pid);
 
 static void delayed_put_pid(struct rcu_head *rhp)
 {
@@ -169,7 +192,7 @@ fastcall void free_pid(struct pid *pid)
        hlist_del_rcu(&pid->pid_chain);
        spin_unlock_irqrestore(&pidmap_lock, flags);
 
-       free_pidmap(pid->nr);
+       free_pidmap(&init_pspace, pid->nr);
        call_rcu(&pid->rcu, delayed_put_pid);
 }
 
@@ -183,7 +206,7 @@ struct pid *alloc_pid(void)
        if (!pid)
                goto out;
 
-       nr = alloc_pidmap();
+       nr = alloc_pidmap(&init_pspace);
        if (nr < 0)
                goto out_free;
 
@@ -217,6 +240,7 @@ struct pid * fastcall find_pid(int nr)
        }
        return NULL;
 }
+EXPORT_SYMBOL_GPL(find_pid);
 
 int fastcall attach_pid(struct task_struct *task, enum pid_type type, int nr)
 {
@@ -280,6 +304,15 @@ struct task_struct *find_task_by_pid_type(int type, int nr)
 
 EXPORT_SYMBOL(find_task_by_pid_type);
 
+struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
+{
+       struct pid *pid;
+       rcu_read_lock();
+       pid = get_pid(task->pids[type].pid);
+       rcu_read_unlock();
+       return pid;
+}
+
 struct task_struct *fastcall get_pid_task(struct pid *pid, enum pid_type type)
 {
        struct task_struct *result;
@@ -302,6 +335,26 @@ struct pid *find_get_pid(pid_t nr)
        return pid;
 }
 
+/*
+ * Used by proc to find the first pid that is greater then or equal to nr.
+ *
+ * If there is a pid at nr this function is exactly the same as find_pid.
+ */
+struct pid *find_ge_pid(int nr)
+{
+       struct pid *pid;
+
+       do {
+               pid = find_pid(nr);
+               if (pid)
+                       break;
+               nr = next_pidmap(&init_pspace, nr);
+       } while (nr > 0);
+
+       return pid;
+}
+EXPORT_SYMBOL_GPL(find_get_pid);
+
 /*
  * The pid hash table is scaled according to the amount of memory in the
  * machine.  From a minimum of 16 slots up to 4096 slots at one gigabyte or
@@ -329,10 +382,10 @@ void __init pidhash_init(void)
 
 void __init pidmap_init(void)
 {
-       pidmap_array->page = (void *)get_zeroed_page(GFP_KERNEL);
+       init_pspace.pidmap[0].page = kzalloc(PAGE_SIZE, GFP_KERNEL);
        /* Reserve PID 0. We never call free_pidmap(0) */
-       set_bit(0, pidmap_array->page);
-       atomic_dec(&pidmap_array->nr_free);
+       set_bit(0, init_pspace.pidmap[0].page);
+       atomic_dec(&init_pspace.pidmap[0].nr_free);
 
        pid_cachep = kmem_cache_create("pid", sizeof(struct pid),
                                        __alignof__(struct pid),
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 1b84313cbab5ad973d69dda99006d8439316af7d..99f9b7d177d6a843f5bcb3ade50e67379e169013 100644 (file)
@@ -906,7 +906,7 @@ static void init_header(struct swsusp_info *info)
        memset(info, 0, sizeof(struct swsusp_info));
        info->version_code = LINUX_VERSION_CODE;
        info->num_physpages = num_physpages;
-       memcpy(&info->uts, &system_utsname, sizeof(system_utsname));
+       memcpy(&info->uts, init_utsname(), sizeof(struct new_utsname));
        info->cpus = num_online_cpus();
        info->image_pages = nr_copy_pages;
        info->pages = nr_copy_pages + nr_meta_pages + 1;
@@ -1050,13 +1050,13 @@ static inline int check_header(struct swsusp_info *info)
                reason = "kernel version";
        if (info->num_physpages != num_physpages)
                reason = "memory size";
-       if (strcmp(info->uts.sysname,system_utsname.sysname))
+       if (strcmp(info->uts.sysname,init_utsname()->sysname))
                reason = "system type";
-       if (strcmp(info->uts.release,system_utsname.release))
+       if (strcmp(info->uts.release,init_utsname()->release))
                reason = "kernel release";
-       if (strcmp(info->uts.version,system_utsname.version))
+       if (strcmp(info->uts.version,init_utsname()->version))
                reason = "version";
-       if (strcmp(info->uts.machine,system_utsname.machine))
+       if (strcmp(info->uts.machine,init_utsname()->machine))
                reason = "machine";
        if (reason) {
                printk(KERN_ERR "swsusp: Resume mismatch: %s\n", reason);
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");
index 9db38a1a75208cb36bb8c68cd51f6ba7b293ce5f..6de60c12143e63f539701c3bc1687f3f21d0df9d 100644 (file)
@@ -193,6 +193,13 @@ static int __release_resource(struct resource *old)
        return -EINVAL;
 }
 
+/**
+ * request_resource - request and reserve an I/O or memory resource
+ * @root: root resource descriptor
+ * @new: resource descriptor desired by caller
+ *
+ * Returns 0 for success, negative error code on error.
+ */
 int request_resource(struct resource *root, struct resource *new)
 {
        struct resource *conflict;
@@ -205,6 +212,15 @@ int request_resource(struct resource *root, struct resource *new)
 
 EXPORT_SYMBOL(request_resource);
 
+/**
+ * ____request_resource - reserve a resource, with resource conflict returned
+ * @root: root resource descriptor
+ * @new: resource descriptor desired by caller
+ *
+ * Returns:
+ * On success, NULL is returned.
+ * On error, a pointer to the conflicting resource is returned.
+ */
 struct resource *____request_resource(struct resource *root, struct resource *new)
 {
        struct resource *conflict;
@@ -217,6 +233,10 @@ struct resource *____request_resource(struct resource *root, struct resource *ne
 
 EXPORT_SYMBOL(____request_resource);
 
+/**
+ * release_resource - release a previously reserved resource
+ * @old: resource pointer
+ */
 int release_resource(struct resource *old)
 {
        int retval;
@@ -315,8 +335,16 @@ static int find_resource(struct resource *root, struct resource *new,
        return -EBUSY;
 }
 
-/*
- * Allocate empty slot in the resource tree given range and alignment.
+/**
+ * allocate_resource - allocate empty slot in the resource tree given range & alignment
+ * @root: root resource descriptor
+ * @new: resource descriptor desired by caller
+ * @size: requested resource region size
+ * @min: minimum size to allocate
+ * @max: maximum size to allocate
+ * @align: alignment requested, in bytes
+ * @alignf: alignment function, optional, called if not NULL
+ * @alignf_data: arbitrary data to pass to the @alignf function
  */
 int allocate_resource(struct resource *root, struct resource *new,
                      resource_size_t size, resource_size_t min,
@@ -407,10 +435,15 @@ int insert_resource(struct resource *parent, struct resource *new)
        return result;
 }
 
-/*
+/**
+ * adjust_resource - modify a resource's start and size
+ * @res: resource to modify
+ * @start: new start value
+ * @size: new size
+ *
  * Given an existing resource, change its start and size to match the
- * arguments.  Returns -EBUSY if it can't fit.  Existing children of
- * the resource are assumed to be immutable.
+ * arguments.  Returns 0 on success, -EBUSY if it can't fit.
+ * Existing children of the resource are assumed to be immutable.
  */
 int adjust_resource(struct resource *res, resource_size_t start, resource_size_t size)
 {
@@ -456,11 +489,19 @@ EXPORT_SYMBOL(adjust_resource);
  * Note how this, unlike the above, knows about
  * the IO flag meanings (busy etc).
  *
- * Request-region creates a new busy region.
+ * request_region creates a new busy region.
  *
- * Check-region returns non-zero if the area is already busy
+ * check_region returns non-zero if the area is already busy.
  *
- * Release-region releases a matching busy region.
+ * release_region releases a matching busy region.
+ */
+
+/**
+ * __request_region - create a new busy resource region
+ * @parent: parent resource descriptor
+ * @start: resource start address
+ * @n: resource region size
+ * @name: reserving caller's ID string
  */
 struct resource * __request_region(struct resource *parent,
                                   resource_size_t start, resource_size_t n,
@@ -497,9 +538,23 @@ struct resource * __request_region(struct resource *parent,
        }
        return res;
 }
-
 EXPORT_SYMBOL(__request_region);
 
+/**
+ * __check_region - check if a resource region is busy or free
+ * @parent: parent resource descriptor
+ * @start: resource start address
+ * @n: resource region size
+ *
+ * Returns 0 if the region is free at the moment it is checked,
+ * returns %-EBUSY if the region is busy.
+ *
+ * NOTE:
+ * This function is deprecated because its use is racy.
+ * Even if it returns 0, a subsequent call to request_region()
+ * may fail because another driver etc. just allocated the region.
+ * Do NOT use it.  It will be removed from the kernel.
+ */
 int __check_region(struct resource *parent, resource_size_t start,
                        resource_size_t n)
 {
@@ -513,9 +568,16 @@ int __check_region(struct resource *parent, resource_size_t start,
        kfree(res);
        return 0;
 }
-
 EXPORT_SYMBOL(__check_region);
 
+/**
+ * __release_region - release a previously reserved resource region
+ * @parent: parent resource descriptor
+ * @start: resource start address
+ * @n: resource region size
+ *
+ * The described resource region must match a currently busy region.
+ */
 void __release_region(struct resource *parent, resource_size_t start,
                        resource_size_t n)
 {
@@ -553,7 +615,6 @@ void __release_region(struct resource *parent, resource_size_t start,
                "<%016llx-%016llx>\n", (unsigned long long)start,
                (unsigned long long)end);
 }
-
 EXPORT_SYMBOL(__release_region);
 
 /*
index 2bbd948f0169dc3361d8b8924b0dce59eda1a825..53608a59d6e3c0fd3d0b18dbf919beb9b0125397 100644 (file)
@@ -1232,7 +1232,7 @@ nextgroup:
 }
 
 /*
- * find_idlest_queue - find the idlest runqueue among the cpus in group.
+ * find_idlest_cpu - find the idlest cpu among the cpus in group.
  */
 static int
 find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu)
@@ -1286,21 +1286,29 @@ static int sched_balance_self(int cpu, int flag)
        while (sd) {
                cpumask_t span;
                struct sched_group *group;
-               int new_cpu;
-               int weight;
+               int new_cpu, weight;
+
+               if (!(sd->flags & flag)) {
+                       sd = sd->child;
+                       continue;
+               }
 
                span = sd->span;
                group = find_idlest_group(sd, t, cpu);
-               if (!group)
-                       goto nextlevel;
+               if (!group) {
+                       sd = sd->child;
+                       continue;
+               }
 
                new_cpu = find_idlest_cpu(group, t, cpu);
-               if (new_cpu == -1 || new_cpu == cpu)
-                       goto nextlevel;
+               if (new_cpu == -1 || new_cpu == cpu) {
+                       /* Now try balancing at a lower domain level of cpu */
+                       sd = sd->child;
+                       continue;
+               }
 
-               /* Now try balancing at a lower domain level */
+               /* Now try balancing at a lower domain level of new_cpu */
                cpu = new_cpu;
-nextlevel:
                sd = NULL;
                weight = cpus_weight(span);
                for_each_domain(cpu, tmp) {
@@ -2533,8 +2541,14 @@ static int load_balance(int this_cpu, struct rq *this_rq,
        struct rq *busiest;
        cpumask_t cpus = CPU_MASK_ALL;
 
+       /*
+        * When power savings policy is enabled for the parent domain, idle
+        * sibling can pick up load irrespective of busy siblings. In this case,
+        * let the state of idle sibling percolate up as IDLE, instead of
+        * portraying it as NOT_IDLE.
+        */
        if (idle != NOT_IDLE && sd->flags & SD_SHARE_CPUPOWER &&
-           !sched_smt_power_savings)
+           !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
                sd_idle = 1;
 
        schedstat_inc(sd, lb_cnt[idle]);
@@ -2630,7 +2644,7 @@ redo:
        }
 
        if (!nr_moved && !sd_idle && sd->flags & SD_SHARE_CPUPOWER &&
-           !sched_smt_power_savings)
+           !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
                return -1;
        return nr_moved;
 
@@ -2646,7 +2660,7 @@ out_one_pinned:
                sd->balance_interval *= 2;
 
        if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER &&
-                       !sched_smt_power_savings)
+           !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
                return -1;
        return 0;
 }
@@ -2668,7 +2682,14 @@ load_balance_newidle(int this_cpu, struct rq *this_rq, struct sched_domain *sd)
        int sd_idle = 0;
        cpumask_t cpus = CPU_MASK_ALL;
 
-       if (sd->flags & SD_SHARE_CPUPOWER && !sched_smt_power_savings)
+       /*
+        * When power savings policy is enabled for the parent domain, idle
+        * sibling can pick up load irrespective of busy siblings. In this case,
+        * let the state of idle sibling percolate up as IDLE, instead of
+        * portraying it as NOT_IDLE.
+        */
+       if (sd->flags & SD_SHARE_CPUPOWER &&
+           !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
                sd_idle = 1;
 
        schedstat_inc(sd, lb_cnt[NEWLY_IDLE]);
@@ -2709,7 +2730,8 @@ redo:
 
        if (!nr_moved) {
                schedstat_inc(sd, lb_failed[NEWLY_IDLE]);
-               if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER)
+               if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER &&
+                   !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
                        return -1;
        } else
                sd->nr_balance_failed = 0;
@@ -2719,7 +2741,7 @@ redo:
 out_balanced:
        schedstat_inc(sd, lb_balanced[NEWLY_IDLE]);
        if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER &&
-                                       !sched_smt_power_savings)
+           !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
                return -1;
        sd->nr_balance_failed = 0;
 
@@ -4384,7 +4406,10 @@ EXPORT_SYMBOL(cpu_present_map);
 
 #ifndef CONFIG_SMP
 cpumask_t cpu_online_map __read_mostly = CPU_MASK_ALL;
+EXPORT_SYMBOL(cpu_online_map);
+
 cpumask_t cpu_possible_map __read_mostly = CPU_MASK_ALL;
+EXPORT_SYMBOL(cpu_possible_map);
 #endif
 
 long sched_getaffinity(pid_t pid, cpumask_t *mask)
@@ -4814,7 +4839,7 @@ void show_state(void)
  * NOTE: this function does not set the idle thread's NEED_RESCHED
  * flag, to make booting more robust.
  */
-void __devinit init_idle(struct task_struct *idle, int cpu)
+void __cpuinit init_idle(struct task_struct *idle, int cpu)
 {
        struct rq *rq = cpu_rq(cpu);
        unsigned long flags;
@@ -5389,7 +5414,9 @@ static int sd_degenerate(struct sched_domain *sd)
        if (sd->flags & (SD_LOAD_BALANCE |
                         SD_BALANCE_NEWIDLE |
                         SD_BALANCE_FORK |
-                        SD_BALANCE_EXEC)) {
+                        SD_BALANCE_EXEC |
+                        SD_SHARE_CPUPOWER |
+                        SD_SHARE_PKG_RESOURCES)) {
                if (sd->groups != sd->groups->next)
                        return 0;
        }
@@ -5423,7 +5450,9 @@ sd_parent_degenerate(struct sched_domain *sd, struct sched_domain *parent)
                pflags &= ~(SD_LOAD_BALANCE |
                                SD_BALANCE_NEWIDLE |
                                SD_BALANCE_FORK |
-                               SD_BALANCE_EXEC);
+                               SD_BALANCE_EXEC |
+                               SD_SHARE_CPUPOWER |
+                               SD_SHARE_PKG_RESOURCES);
        }
        if (~cflags & pflags)
                return 0;
@@ -5445,12 +5474,18 @@ static void cpu_attach_domain(struct sched_domain *sd, int cpu)
                struct sched_domain *parent = tmp->parent;
                if (!parent)
                        break;
-               if (sd_parent_degenerate(tmp, parent))
+               if (sd_parent_degenerate(tmp, parent)) {
                        tmp->parent = parent->parent;
+                       if (parent->parent)
+                               parent->parent->child = tmp;
+               }
        }
 
-       if (sd && sd_degenerate(sd))
+       if (sd && sd_degenerate(sd)) {
                sd = sd->parent;
+               if (sd)
+                       sd->child = NULL;
+       }
 
        sched_domain_debug(sd, cpu);
 
@@ -5458,7 +5493,7 @@ static void cpu_attach_domain(struct sched_domain *sd, int cpu)
 }
 
 /* cpus with isolated domains */
-static cpumask_t __devinitdata cpu_isolated_map = CPU_MASK_NONE;
+static cpumask_t __cpuinitdata cpu_isolated_map = CPU_MASK_NONE;
 
 /* Setup the mask of cpus configured for isolated domains */
 static int __init isolated_cpu_setup(char *str)
@@ -5486,15 +5521,17 @@ __setup ("isolcpus=", isolated_cpu_setup);
  * covered by the given span, and will set each group's ->cpumask correctly,
  * and ->cpu_power to 0.
  */
-static void init_sched_build_groups(struct sched_group groups[], cpumask_t span,
-                                   int (*group_fn)(int cpu))
+static void
+init_sched_build_groups(struct sched_group groups[], cpumask_t span,
+                       const cpumask_t *cpu_map,
+                       int (*group_fn)(int cpu, const cpumask_t *cpu_map))
 {
        struct sched_group *first = NULL, *last = NULL;
        cpumask_t covered = CPU_MASK_NONE;
        int i;
 
        for_each_cpu_mask(i, span) {
-               int group = group_fn(i);
+               int group = group_fn(i, cpu_map);
                struct sched_group *sg = &groups[group];
                int j;
 
@@ -5505,7 +5542,7 @@ static void init_sched_build_groups(struct sched_group groups[], cpumask_t span,
                sg->cpu_power = 0;
 
                for_each_cpu_mask(j, span) {
-                       if (group_fn(j) != group)
+                       if (group_fn(j, cpu_map) != group)
                                continue;
 
                        cpu_set(j, covered);
@@ -5972,13 +6009,15 @@ static void calibrate_migration_costs(const cpumask_t *cpu_map)
 #endif
                );
        if (system_state == SYSTEM_BOOTING) {
-               printk("migration_cost=");
-               for (distance = 0; distance <= max_distance; distance++) {
-                       if (distance)
-                               printk(",");
-                       printk("%ld", (long)migration_cost[distance] / 1000);
+               if (num_online_cpus() > 1) {
+                       printk("migration_cost=");
+                       for (distance = 0; distance <= max_distance; distance++) {
+                               if (distance)
+                                       printk(",");
+                               printk("%ld", (long)migration_cost[distance] / 1000);
+                       }
+                       printk("\n");
                }
-               printk("\n");
        }
        j1 = jiffies;
        if (migration_debug)
@@ -6081,7 +6120,7 @@ int sched_smt_power_savings = 0, sched_mc_power_savings = 0;
 static DEFINE_PER_CPU(struct sched_domain, cpu_domains);
 static struct sched_group sched_group_cpus[NR_CPUS];
 
-static int cpu_to_cpu_group(int cpu)
+static int cpu_to_cpu_group(int cpu, const cpumask_t *cpu_map)
 {
        return cpu;
 }
@@ -6092,31 +6131,36 @@ static int cpu_to_cpu_group(int cpu)
  */
 #ifdef CONFIG_SCHED_MC
 static DEFINE_PER_CPU(struct sched_domain, core_domains);
-static struct sched_group *sched_group_core_bycpu[NR_CPUS];
+static struct sched_group sched_group_core[NR_CPUS];
 #endif
 
 #if defined(CONFIG_SCHED_MC) && defined(CONFIG_SCHED_SMT)
-static int cpu_to_core_group(int cpu)
+static int cpu_to_core_group(int cpu, const cpumask_t *cpu_map)
 {
-       return first_cpu(cpu_sibling_map[cpu]);
+       cpumask_t mask = cpu_sibling_map[cpu];
+       cpus_and(mask, mask, *cpu_map);
+       return first_cpu(mask);
 }
 #elif defined(CONFIG_SCHED_MC)
-static int cpu_to_core_group(int cpu)
+static int cpu_to_core_group(int cpu, const cpumask_t *cpu_map)
 {
        return cpu;
 }
 #endif
 
 static DEFINE_PER_CPU(struct sched_domain, phys_domains);
-static struct sched_group *sched_group_phys_bycpu[NR_CPUS];
+static struct sched_group sched_group_phys[NR_CPUS];
 
-static int cpu_to_phys_group(int cpu)
+static int cpu_to_phys_group(int cpu, const cpumask_t *cpu_map)
 {
 #ifdef CONFIG_SCHED_MC
        cpumask_t mask = cpu_coregroup_map(cpu);
+       cpus_and(mask, mask, *cpu_map);
        return first_cpu(mask);
 #elif defined(CONFIG_SCHED_SMT)
-       return first_cpu(cpu_sibling_map[cpu]);
+       cpumask_t mask = cpu_sibling_map[cpu];
+       cpus_and(mask, mask, *cpu_map);
+       return first_cpu(mask);
 #else
        return cpu;
 #endif
@@ -6134,7 +6178,7 @@ static struct sched_group **sched_group_nodes_bycpu[NR_CPUS];
 static DEFINE_PER_CPU(struct sched_domain, allnodes_domains);
 static struct sched_group *sched_group_allnodes_bycpu[NR_CPUS];
 
-static int cpu_to_allnodes_group(int cpu)
+static int cpu_to_allnodes_group(int cpu, const cpumask_t *cpu_map)
 {
        return cpu_to_node(cpu);
 }
@@ -6166,12 +6210,11 @@ next_sg:
 }
 #endif
 
+#ifdef CONFIG_NUMA
 /* Free memory allocated for various sched_group structures */
 static void free_sched_groups(const cpumask_t *cpu_map)
 {
-       int cpu;
-#ifdef CONFIG_NUMA
-       int i;
+       int cpu, i;
 
        for_each_cpu_mask(cpu, *cpu_map) {
                struct sched_group *sched_group_allnodes
@@ -6208,19 +6251,63 @@ next_sg:
                kfree(sched_group_nodes);
                sched_group_nodes_bycpu[cpu] = NULL;
        }
+}
+#else
+static void free_sched_groups(const cpumask_t *cpu_map)
+{
+}
 #endif
-       for_each_cpu_mask(cpu, *cpu_map) {
-               if (sched_group_phys_bycpu[cpu]) {
-                       kfree(sched_group_phys_bycpu[cpu]);
-                       sched_group_phys_bycpu[cpu] = NULL;
-               }
-#ifdef CONFIG_SCHED_MC
-               if (sched_group_core_bycpu[cpu]) {
-                       kfree(sched_group_core_bycpu[cpu]);
-                       sched_group_core_bycpu[cpu] = NULL;
-               }
-#endif
+
+/*
+ * Initialize sched groups cpu_power.
+ *
+ * cpu_power indicates the capacity of sched group, which is used while
+ * distributing the load between different sched groups in a sched domain.
+ * Typically cpu_power for all the groups in a sched domain will be same unless
+ * there are asymmetries in the topology. If there are asymmetries, group
+ * having more cpu_power will pickup more load compared to the group having
+ * less cpu_power.
+ *
+ * cpu_power will be a multiple of SCHED_LOAD_SCALE. This multiple represents
+ * the maximum number of tasks a group can handle in the presence of other idle
+ * or lightly loaded groups in the same sched domain.
+ */
+static void init_sched_groups_power(int cpu, struct sched_domain *sd)
+{
+       struct sched_domain *child;
+       struct sched_group *group;
+
+       WARN_ON(!sd || !sd->groups);
+
+       if (cpu != first_cpu(sd->groups->cpumask))
+               return;
+
+       child = sd->child;
+
+       /*
+        * For perf policy, if the groups in child domain share resources
+        * (for example cores sharing some portions of the cache hierarchy
+        * or SMT), then set this domain groups cpu_power such that each group
+        * can handle only one task, when there are other idle groups in the
+        * same sched domain.
+        */
+       if (!child || (!(sd->flags & SD_POWERSAVINGS_BALANCE) &&
+                      (child->flags &
+                       (SD_SHARE_CPUPOWER | SD_SHARE_PKG_RESOURCES)))) {
+               sd->groups->cpu_power = SCHED_LOAD_SCALE;
+               return;
        }
+
+       sd->groups->cpu_power = 0;
+
+       /*
+        * add cpu_power of each child group to this groups cpu_power
+        */
+       group = child->groups;
+       do {
+               sd->groups->cpu_power += group->cpu_power;
+               group = group->next;
+       } while (group != child->groups);
 }
 
 /*
@@ -6230,10 +6317,7 @@ next_sg:
 static int build_sched_domains(const cpumask_t *cpu_map)
 {
        int i;
-       struct sched_group *sched_group_phys = NULL;
-#ifdef CONFIG_SCHED_MC
-       struct sched_group *sched_group_core = NULL;
-#endif
+       struct sched_domain *sd;
 #ifdef CONFIG_NUMA
        struct sched_group **sched_group_nodes = NULL;
        struct sched_group *sched_group_allnodes = NULL;
@@ -6265,9 +6349,10 @@ static int build_sched_domains(const cpumask_t *cpu_map)
                                > SD_NODES_PER_DOMAIN*cpus_weight(nodemask)) {
                        if (!sched_group_allnodes) {
                                sched_group_allnodes
-                                       = kmalloc(sizeof(struct sched_group)
-                                                       * MAX_NUMNODES,
-                                                 GFP_KERNEL);
+                                       = kmalloc_node(sizeof(struct sched_group)
+                                                       * MAX_NUMNODES,
+                                                 GFP_KERNEL,
+                                                 cpu_to_node(i));
                                if (!sched_group_allnodes) {
                                        printk(KERN_WARNING
                                        "Can not alloc allnodes sched group\n");
@@ -6279,7 +6364,7 @@ static int build_sched_domains(const cpumask_t *cpu_map)
                        sd = &per_cpu(allnodes_domains, i);
                        *sd = SD_ALLNODES_INIT;
                        sd->span = *cpu_map;
-                       group = cpu_to_allnodes_group(i);
+                       group = cpu_to_allnodes_group(i, cpu_map);
                        sd->groups = &sched_group_allnodes[group];
                        p = sd;
                } else
@@ -6289,60 +6374,42 @@ static int build_sched_domains(const cpumask_t *cpu_map)
                *sd = SD_NODE_INIT;
                sd->span = sched_domain_node_span(cpu_to_node(i));
                sd->parent = p;
+               if (p)
+                       p->child = sd;
                cpus_and(sd->span, sd->span, *cpu_map);
 #endif
 
-               if (!sched_group_phys) {
-                       sched_group_phys
-                               = kmalloc(sizeof(struct sched_group) * NR_CPUS,
-                                         GFP_KERNEL);
-                       if (!sched_group_phys) {
-                               printk (KERN_WARNING "Can not alloc phys sched"
-                                                    "group\n");
-                               goto error;
-                       }
-                       sched_group_phys_bycpu[i] = sched_group_phys;
-               }
-
                p = sd;
                sd = &per_cpu(phys_domains, i);
-               group = cpu_to_phys_group(i);
+               group = cpu_to_phys_group(i, cpu_map);
                *sd = SD_CPU_INIT;
                sd->span = nodemask;
                sd->parent = p;
+               if (p)
+                       p->child = sd;
                sd->groups = &sched_group_phys[group];
 
 #ifdef CONFIG_SCHED_MC
-               if (!sched_group_core) {
-                       sched_group_core
-                               = kmalloc(sizeof(struct sched_group) * NR_CPUS,
-                                         GFP_KERNEL);
-                       if (!sched_group_core) {
-                               printk (KERN_WARNING "Can not alloc core sched"
-                                                    "group\n");
-                               goto error;
-                       }
-                       sched_group_core_bycpu[i] = sched_group_core;
-               }
-
                p = sd;
                sd = &per_cpu(core_domains, i);
-               group = cpu_to_core_group(i);
+               group = cpu_to_core_group(i, cpu_map);
                *sd = SD_MC_INIT;
                sd->span = cpu_coregroup_map(i);
                cpus_and(sd->span, sd->span, *cpu_map);
                sd->parent = p;
+               p->child = sd;
                sd->groups = &sched_group_core[group];
 #endif
 
 #ifdef CONFIG_SCHED_SMT
                p = sd;
                sd = &per_cpu(cpu_domains, i);
-               group = cpu_to_cpu_group(i);
+               group = cpu_to_cpu_group(i, cpu_map);
                *sd = SD_SIBLING_INIT;
                sd->span = cpu_sibling_map[i];
                cpus_and(sd->span, sd->span, *cpu_map);
                sd->parent = p;
+               p->child = sd;
                sd->groups = &sched_group_cpus[group];
 #endif
        }
@@ -6356,7 +6423,7 @@ static int build_sched_domains(const cpumask_t *cpu_map)
                        continue;
 
                init_sched_build_groups(sched_group_cpus, this_sibling_map,
-                                               &cpu_to_cpu_group);
+                                       cpu_map, &cpu_to_cpu_group);
        }
 #endif
 
@@ -6368,7 +6435,7 @@ static int build_sched_domains(const cpumask_t *cpu_map)
                if (i != first_cpu(this_core_map))
                        continue;
                init_sched_build_groups(sched_group_core, this_core_map,
-                                       &cpu_to_core_group);
+                                       cpu_map, &cpu_to_core_group);
        }
 #endif
 
@@ -6382,14 +6449,14 @@ static int build_sched_domains(const cpumask_t *cpu_map)
                        continue;
 
                init_sched_build_groups(sched_group_phys, nodemask,
-                                               &cpu_to_phys_group);
+                                       cpu_map, &cpu_to_phys_group);
        }
 
 #ifdef CONFIG_NUMA
        /* Set up node groups */
        if (sched_group_allnodes)
                init_sched_build_groups(sched_group_allnodes, *cpu_map,
-                                       &cpu_to_allnodes_group);
+                                       cpu_map, &cpu_to_allnodes_group);
 
        for (i = 0; i < MAX_NUMNODES; i++) {
                /* Set up node groups */
@@ -6461,72 +6528,20 @@ static int build_sched_domains(const cpumask_t *cpu_map)
        /* Calculate CPU power for physical packages and nodes */
 #ifdef CONFIG_SCHED_SMT
        for_each_cpu_mask(i, *cpu_map) {
-               struct sched_domain *sd;
                sd = &per_cpu(cpu_domains, i);
-               sd->groups->cpu_power = SCHED_LOAD_SCALE;
+               init_sched_groups_power(i, sd);
        }
 #endif
 #ifdef CONFIG_SCHED_MC
        for_each_cpu_mask(i, *cpu_map) {
-               int power;
-               struct sched_domain *sd;
                sd = &per_cpu(core_domains, i);
-               if (sched_smt_power_savings)
-                       power = SCHED_LOAD_SCALE * cpus_weight(sd->groups->cpumask);
-               else
-                       power = SCHED_LOAD_SCALE + (cpus_weight(sd->groups->cpumask)-1)
-                                           * SCHED_LOAD_SCALE / 10;
-               sd->groups->cpu_power = power;
+               init_sched_groups_power(i, sd);
        }
 #endif
 
        for_each_cpu_mask(i, *cpu_map) {
-               struct sched_domain *sd;
-#ifdef CONFIG_SCHED_MC
                sd = &per_cpu(phys_domains, i);
-               if (i != first_cpu(sd->groups->cpumask))
-                       continue;
-
-               sd->groups->cpu_power = 0;
-               if (sched_mc_power_savings || sched_smt_power_savings) {
-                       int j;
-
-                       for_each_cpu_mask(j, sd->groups->cpumask) {
-                               struct sched_domain *sd1;
-                               sd1 = &per_cpu(core_domains, j);
-                               /*
-                                * for each core we will add once
-                                * to the group in physical domain
-                                */
-                               if (j != first_cpu(sd1->groups->cpumask))
-                                       continue;
-
-                               if (sched_smt_power_savings)
-                                       sd->groups->cpu_power += sd1->groups->cpu_power;
-                               else
-                                       sd->groups->cpu_power += SCHED_LOAD_SCALE;
-                       }
-               } else
-                       /*
-                        * This has to be < 2 * SCHED_LOAD_SCALE
-                        * Lets keep it SCHED_LOAD_SCALE, so that
-                        * while calculating NUMA group's cpu_power
-                        * we can simply do
-                        *  numa_group->cpu_power += phys_group->cpu_power;
-                        *
-                        * See "only add power once for each physical pkg"
-                        * comment below
-                        */
-                       sd->groups->cpu_power = SCHED_LOAD_SCALE;
-#else
-               int power;
-               sd = &per_cpu(phys_domains, i);
-               if (sched_smt_power_savings)
-                       power = SCHED_LOAD_SCALE * cpus_weight(sd->groups->cpumask);
-               else
-                       power = SCHED_LOAD_SCALE;
-               sd->groups->cpu_power = power;
-#endif
+               init_sched_groups_power(i, sd);
        }
 
 #ifdef CONFIG_NUMA
@@ -6534,7 +6549,7 @@ static int build_sched_domains(const cpumask_t *cpu_map)
                init_numa_sched_groups_power(sched_group_nodes[i]);
 
        if (sched_group_allnodes) {
-               int group = cpu_to_allnodes_group(first_cpu(*cpu_map));
+               int group = cpu_to_allnodes_group(first_cpu(*cpu_map), cpu_map);
                struct sched_group *sg = &sched_group_allnodes[group];
 
                init_numa_sched_groups_power(sg);
@@ -6560,9 +6575,11 @@ static int build_sched_domains(const cpumask_t *cpu_map)
 
        return 0;
 
+#ifdef CONFIG_NUMA
 error:
        free_sched_groups(cpu_map);
        return -ENOMEM;
+#endif
 }
 /*
  * Set up scheduler domains and groups.  Callers must hold the hotplug lock.
@@ -6744,11 +6761,20 @@ static int update_sched_domains(struct notifier_block *nfb,
 
 void __init sched_init_smp(void)
 {
+       cpumask_t non_isolated_cpus;
+
        lock_cpu_hotplug();
        arch_init_sched_domains(&cpu_online_map);
+       cpus_andnot(non_isolated_cpus, cpu_online_map, cpu_isolated_map);
+       if (cpus_empty(non_isolated_cpus))
+               cpu_set(smp_processor_id(), non_isolated_cpus);
        unlock_cpu_hotplug();
        /* XXX: Theoretical race here - CPU may be hotplugged now */
        hotcpu_notifier(update_sched_domains, 0);
+
+       /* Move init over to a non-isolated CPU */
+       if (set_cpus_allowed(current, non_isolated_cpus) < 0)
+               BUG();
 }
 #else
 void __init sched_init_smp(void)
index fb5da6d19f14eef721f28750307c9654f17a8bfa..7ed8d5304bec2d2c9e51099f5c66ff304d40946a 100644 (file)
@@ -1055,28 +1055,44 @@ int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
 }
 
 /*
- * kill_pg_info() sends a signal to a process group: this is what the tty
+ * kill_pgrp_info() sends a signal to a process group: this is what the tty
  * control characters do (^C, ^Z etc)
  */
 
-int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp)
+int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp)
 {
        struct task_struct *p = NULL;
        int retval, success;
 
-       if (pgrp <= 0)
-               return -EINVAL;
-
        success = 0;
        retval = -ESRCH;
-       do_each_task_pid(pgrp, PIDTYPE_PGID, p) {
+       do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
                int err = group_send_sig_info(sig, info, p);
                success |= !err;
                retval = err;
-       } while_each_task_pid(pgrp, PIDTYPE_PGID, p);
+       } while_each_pid_task(pgrp, PIDTYPE_PGID, p);
        return success ? 0 : retval;
 }
 
+int kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp)
+{
+       int retval;
+
+       read_lock(&tasklist_lock);
+       retval = __kill_pgrp_info(sig, info, pgrp);
+       read_unlock(&tasklist_lock);
+
+       return retval;
+}
+
+int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp)
+{
+       if (pgrp <= 0)
+               return -EINVAL;
+
+       return __kill_pgrp_info(sig, info, find_pid(pgrp));
+}
+
 int
 kill_pg_info(int sig, struct siginfo *info, pid_t pgrp)
 {
@@ -1089,8 +1105,7 @@ kill_pg_info(int sig, struct siginfo *info, pid_t pgrp)
        return retval;
 }
 
-int
-kill_proc_info(int sig, struct siginfo *info, pid_t pid)
+int kill_pid_info(int sig, struct siginfo *info, struct pid *pid)
 {
        int error;
        int acquired_tasklist_lock = 0;
@@ -1101,7 +1116,7 @@ kill_proc_info(int sig, struct siginfo *info, pid_t pid)
                read_lock(&tasklist_lock);
                acquired_tasklist_lock = 1;
        }
-       p = find_task_by_pid(pid);
+       p = pid_task(pid, PIDTYPE_PID);
        error = -ESRCH;
        if (p)
                error = group_send_sig_info(sig, info, p);
@@ -1111,8 +1126,18 @@ kill_proc_info(int sig, struct siginfo *info, pid_t pid)
        return error;
 }
 
-/* like kill_proc_info(), but doesn't use uid/euid of "current" */
-int kill_proc_info_as_uid(int sig, struct siginfo *info, pid_t pid,
+int
+kill_proc_info(int sig, struct siginfo *info, pid_t pid)
+{
+       int error;
+       rcu_read_lock();
+       error = kill_pid_info(sig, info, find_pid(pid));
+       rcu_read_unlock();
+       return error;
+}
+
+/* like kill_pid_info(), but doesn't use uid/euid of "current" */
+int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid,
                      uid_t uid, uid_t euid, u32 secid)
 {
        int ret = -EINVAL;
@@ -1122,7 +1147,7 @@ int kill_proc_info_as_uid(int sig, struct siginfo *info, pid_t pid,
                return ret;
 
        read_lock(&tasklist_lock);
-       p = find_task_by_pid(pid);
+       p = pid_task(pid, PIDTYPE_PID);
        if (!p) {
                ret = -ESRCH;
                goto out_unlock;
@@ -1146,7 +1171,7 @@ out_unlock:
        read_unlock(&tasklist_lock);
        return ret;
 }
-EXPORT_SYMBOL_GPL(kill_proc_info_as_uid);
+EXPORT_SYMBOL_GPL(kill_pid_info_as_uid);
 
 /*
  * kill_something_info() interprets pid in interesting ways just like kill(2).
@@ -1264,6 +1289,18 @@ force_sigsegv(int sig, struct task_struct *p)
        return 0;
 }
 
+int kill_pgrp(struct pid *pid, int sig, int priv)
+{
+       return kill_pgrp_info(sig, __si_special(priv), pid);
+}
+EXPORT_SYMBOL(kill_pgrp);
+
+int kill_pid(struct pid *pid, int sig, int priv)
+{
+       return kill_pid_info(sig, __si_special(priv), pid);
+}
+EXPORT_SYMBOL(kill_pid);
+
 int
 kill_pg(pid_t pgrp, int sig, int priv)
 {
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 2460581c928cf504ee2f81363d1c609b19136515..98489d82801be030cb3477589ed952291e19eb7e 100644 (file)
@@ -92,7 +92,8 @@ EXPORT_SYMBOL(fs_overflowgid);
  */
 
 int C_A_D = 1;
-int cad_pid = 1;
+struct pid *cad_pid;
+EXPORT_SYMBOL(cad_pid);
 
 /*
  *     Notifier list for kernel code which wants to be called
@@ -152,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).
  */
 
 /**
@@ -221,7 +222,7 @@ EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister);
  *     of the last notifier function called.
  */
  
-int atomic_notifier_call_chain(struct atomic_notifier_head *nh,
+int __kprobes atomic_notifier_call_chain(struct atomic_notifier_head *nh,
                unsigned long val, void *v)
 {
        int ret;
@@ -400,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
@@ -773,10 +897,9 @@ void ctrl_alt_del(void)
        if (C_A_D)
                schedule_work(&cad_work);
        else
-               kill_proc(cad_pid, SIGINT, 1);
+               kill_cad_pid(SIGINT, 1);
 }
        
-
 /*
  * Unprivileged users may change the real gid to the effective gid
  * or vice versa.  (BSD-style)
@@ -1655,7 +1778,7 @@ asmlinkage long sys_newuname(struct new_utsname __user * name)
        int errno = 0;
 
        down_read(&uts_sem);
-       if (copy_to_user(name,&system_utsname,sizeof *name))
+       if (copy_to_user(name, utsname(), sizeof *name))
                errno = -EFAULT;
        up_read(&uts_sem);
        return errno;
@@ -1673,8 +1796,8 @@ asmlinkage long sys_sethostname(char __user *name, int len)
        down_write(&uts_sem);
        errno = -EFAULT;
        if (!copy_from_user(tmp, name, len)) {
-               memcpy(system_utsname.nodename, tmp, len);
-               system_utsname.nodename[len] = 0;
+               memcpy(utsname()->nodename, tmp, len);
+               utsname()->nodename[len] = 0;
                errno = 0;
        }
        up_write(&uts_sem);
@@ -1690,11 +1813,11 @@ asmlinkage long sys_gethostname(char __user *name, int len)
        if (len < 0)
                return -EINVAL;
        down_read(&uts_sem);
-       i = 1 + strlen(system_utsname.nodename);
+       i = 1 + strlen(utsname()->nodename);
        if (i > len)
                i = len;
        errno = 0;
-       if (copy_to_user(name, system_utsname.nodename, i))
+       if (copy_to_user(name, utsname()->nodename, i))
                errno = -EFAULT;
        up_read(&uts_sem);
        return errno;
@@ -1719,8 +1842,8 @@ asmlinkage long sys_setdomainname(char __user *name, int len)
        down_write(&uts_sem);
        errno = -EFAULT;
        if (!copy_from_user(tmp, name, len)) {
-               memcpy(system_utsname.domainname, tmp, len);
-               system_utsname.domainname[len] = 0;
+               memcpy(utsname()->domainname, tmp, len);
+               utsname()->domainname[len] = 0;
                errno = 0;
        }
        up_write(&uts_sem);
index ba42694f0453d774d7666b794c6422af21935d75..8020fb273c4f1d0ddce105037bc7803b3c98331a 100644 (file)
@@ -68,7 +68,6 @@ extern int sysrq_enabled;
 extern int core_uses_pid;
 extern int suid_dumpable;
 extern char core_pattern[];
-extern int cad_pid;
 extern int pid_max;
 extern int min_free_kbytes;
 extern int printk_ratelimit_jiffies;
@@ -92,13 +91,8 @@ extern char modprobe_path[];
 extern int sg_big_buff;
 #endif
 #ifdef CONFIG_SYSVIPC
-extern size_t shm_ctlmax;
-extern size_t shm_ctlall;
-extern int shm_ctlmni;
-extern int msg_ctlmax;
-extern int msg_ctlmnb;
-extern int msg_ctlmni;
-extern int sem_ctls[];
+static int proc_do_ipc_string(ctl_table *table, int write, struct file *filp,
+               void __user *buffer, size_t *lenp, loff_t *ppos);
 #endif
 
 #ifdef __sparc__
@@ -139,7 +133,10 @@ static int parse_table(int __user *, int, void __user *, size_t __user *,
                void __user *, size_t, ctl_table *, void **);
 #endif
 
-static int proc_doutsstring(ctl_table *table, int write, struct file *filp,
+static int proc_do_uts_string(ctl_table *table, int write, struct file *filp,
+                 void __user *buffer, size_t *lenp, loff_t *ppos);
+
+static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
                  void __user *buffer, size_t *lenp, loff_t *ppos);
 
 static ctl_table root_table[];
@@ -229,51 +226,100 @@ static ctl_table root_table[] = {
 };
 
 static ctl_table kern_table[] = {
+#ifndef CONFIG_UTS_NS
+       {
+               .ctl_name       = KERN_OSTYPE,
+               .procname       = "ostype",
+               .data           = init_uts_ns.name.sysname,
+               .maxlen         = sizeof(init_uts_ns.name.sysname),
+               .mode           = 0444,
+               .proc_handler   = &proc_do_uts_string,
+               .strategy       = &sysctl_string,
+       },
+       {
+               .ctl_name       = KERN_OSRELEASE,
+               .procname       = "osrelease",
+               .data           = init_uts_ns.name.release,
+               .maxlen         = sizeof(init_uts_ns.name.release),
+               .mode           = 0444,
+               .proc_handler   = &proc_do_uts_string,
+               .strategy       = &sysctl_string,
+       },
+       {
+               .ctl_name       = KERN_VERSION,
+               .procname       = "version",
+               .data           = init_uts_ns.name.version,
+               .maxlen         = sizeof(init_uts_ns.name.version),
+               .mode           = 0444,
+               .proc_handler   = &proc_do_uts_string,
+               .strategy       = &sysctl_string,
+       },
+       {
+               .ctl_name       = KERN_NODENAME,
+               .procname       = "hostname",
+               .data           = init_uts_ns.name.nodename,
+               .maxlen         = sizeof(init_uts_ns.name.nodename),
+               .mode           = 0644,
+               .proc_handler   = &proc_do_uts_string,
+               .strategy       = &sysctl_string,
+       },
+       {
+               .ctl_name       = KERN_DOMAINNAME,
+               .procname       = "domainname",
+               .data           = init_uts_ns.name.domainname,
+               .maxlen         = sizeof(init_uts_ns.name.domainname),
+               .mode           = 0644,
+               .proc_handler   = &proc_do_uts_string,
+               .strategy       = &sysctl_string,
+       },
+#else  /* !CONFIG_UTS_NS */
        {
                .ctl_name       = KERN_OSTYPE,
                .procname       = "ostype",
-               .data           = system_utsname.sysname,
-               .maxlen         = sizeof(system_utsname.sysname),
+               .data           = NULL,
+               /* could maybe use __NEW_UTS_LEN here? */
+               .maxlen         = FIELD_SIZEOF(struct new_utsname, sysname),
                .mode           = 0444,
-               .proc_handler   = &proc_doutsstring,
+               .proc_handler   = &proc_do_uts_string,
                .strategy       = &sysctl_string,
        },
        {
                .ctl_name       = KERN_OSRELEASE,
                .procname       = "osrelease",
-               .data           = system_utsname.release,
-               .maxlen         = sizeof(system_utsname.release),
+               .data           = NULL,
+               .maxlen         = FIELD_SIZEOF(struct new_utsname, release),
                .mode           = 0444,
-               .proc_handler   = &proc_doutsstring,
+               .proc_handler   = &proc_do_uts_string,
                .strategy       = &sysctl_string,
        },
        {
                .ctl_name       = KERN_VERSION,
                .procname       = "version",
-               .data           = system_utsname.version,
-               .maxlen         = sizeof(system_utsname.version),
+               .data           = NULL,
+               .maxlen         = FIELD_SIZEOF(struct new_utsname, version),
                .mode           = 0444,
-               .proc_handler   = &proc_doutsstring,
+               .proc_handler   = &proc_do_uts_string,
                .strategy       = &sysctl_string,
        },
        {
                .ctl_name       = KERN_NODENAME,
                .procname       = "hostname",
-               .data           = system_utsname.nodename,
-               .maxlen         = sizeof(system_utsname.nodename),
+               .data           = NULL,
+               .maxlen         = FIELD_SIZEOF(struct new_utsname, nodename),
                .mode           = 0644,
-               .proc_handler   = &proc_doutsstring,
+               .proc_handler   = &proc_do_uts_string,
                .strategy       = &sysctl_string,
        },
        {
                .ctl_name       = KERN_DOMAINNAME,
                .procname       = "domainname",
-               .data           = system_utsname.domainname,
-               .maxlen         = sizeof(system_utsname.domainname),
+               .data           = NULL,
+               .maxlen         = FIELD_SIZEOF(struct new_utsname, domainname),
                .mode           = 0644,
-               .proc_handler   = &proc_doutsstring,
+               .proc_handler   = &proc_do_uts_string,
                .strategy       = &sysctl_string,
        },
+#endif /* !CONFIG_UTS_NS */
        {
                .ctl_name       = KERN_PANIC,
                .procname       = "panic",
@@ -432,58 +478,58 @@ static ctl_table kern_table[] = {
        {
                .ctl_name       = KERN_SHMMAX,
                .procname       = "shmmax",
-               .data           = &shm_ctlmax,
+               .data           = NULL,
                .maxlen         = sizeof (size_t),
                .mode           = 0644,
-               .proc_handler   = &proc_doulongvec_minmax,
+               .proc_handler   = &proc_do_ipc_string,
        },
        {
                .ctl_name       = KERN_SHMALL,
                .procname       = "shmall",
-               .data           = &shm_ctlall,
+               .data           = NULL,
                .maxlen         = sizeof (size_t),
                .mode           = 0644,
-               .proc_handler   = &proc_doulongvec_minmax,
+               .proc_handler   = &proc_do_ipc_string,
        },
        {
                .ctl_name       = KERN_SHMMNI,
                .procname       = "shmmni",
-               .data           = &shm_ctlmni,
+               .data           = NULL,
                .maxlen         = sizeof (int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = &proc_do_ipc_string,
        },
        {
                .ctl_name       = KERN_MSGMAX,
                .procname       = "msgmax",
-               .data           = &msg_ctlmax,
+               .data           = NULL,
                .maxlen         = sizeof (int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = &proc_do_ipc_string,
        },
        {
                .ctl_name       = KERN_MSGMNI,
                .procname       = "msgmni",
-               .data           = &msg_ctlmni,
+               .data           = NULL,
                .maxlen         = sizeof (int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = &proc_do_ipc_string,
        },
        {
                .ctl_name       = KERN_MSGMNB,
                .procname       =  "msgmnb",
-               .data           = &msg_ctlmnb,
+               .data           = NULL,
                .maxlen         = sizeof (int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = &proc_do_ipc_string,
        },
        {
                .ctl_name       = KERN_SEM,
                .procname       = "sem",
-               .data           = &sem_ctls,
+               .data           = NULL,
                .maxlen         = 4*sizeof (int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = &proc_do_ipc_string,
        },
 #endif
 #ifdef CONFIG_MAGIC_SYSRQ
@@ -499,10 +545,10 @@ static ctl_table kern_table[] = {
        {
                .ctl_name       = KERN_CADPID,
                .procname       = "cad_pid",
-               .data           = &cad_pid,
+               .data           = NULL,
                .maxlen         = sizeof (int),
                .mode           = 0600,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = &proc_do_cad_pid,
        },
        {
                .ctl_name       = KERN_MAX_THREADS,
@@ -1624,32 +1670,15 @@ static ssize_t proc_writesys(struct file * file, const char __user * buf,
        return do_rw_proc(1, file, (char __user *) buf, count, ppos);
 }
 
-/**
- * proc_dostring - read a string sysctl
- * @table: the sysctl table
- * @write: %TRUE if this is a write to the sysctl file
- * @filp: the file structure
- * @buffer: the user buffer
- * @lenp: the size of the user buffer
- * @ppos: file position
- *
- * Reads/writes a string from/to the user buffer. If the kernel
- * buffer provided is not large enough to hold the string, the
- * string is truncated. The copied string is %NULL-terminated.
- * If the string is being read by the user process, it is copied
- * and a newline '\n' is added. It is truncated if the buffer is
- * not large enough.
- *
- * Returns 0 on success.
- */
-int proc_dostring(ctl_table *table, int write, struct file *filp,
-                 void __user *buffer, size_t *lenp, loff_t *ppos)
+static int _proc_do_string(void* data, int maxlen, int write,
+                          struct file *filp, void __user *buffer,
+                          size_t *lenp, loff_t *ppos)
 {
        size_t len;
        char __user *p;
        char c;
        
-       if (!table->data || !table->maxlen || !*lenp ||
+       if (!data || !maxlen || !*lenp ||
            (*ppos && !write)) {
                *lenp = 0;
                return 0;
@@ -1665,20 +1694,20 @@ int proc_dostring(ctl_table *table, int write, struct file *filp,
                                break;
                        len++;
                }
-               if (len >= table->maxlen)
-                       len = table->maxlen-1;
-               if(copy_from_user(table->data, buffer, len))
+               if (len >= maxlen)
+                       len = maxlen-1;
+               if(copy_from_user(data, buffer, len))
                        return -EFAULT;
-               ((char *) table->data)[len] = 0;
+               ((char *) data)[len] = 0;
                *ppos += *lenp;
        } else {
-               len = strlen(table->data);
-               if (len > table->maxlen)
-                       len = table->maxlen;
+               len = strlen(data);
+               if (len > maxlen)
+                       len = maxlen;
                if (len > *lenp)
                        len = *lenp;
                if (len)
-                       if(copy_to_user(buffer, table->data, len))
+                       if(copy_to_user(buffer, data, len))
                                return -EFAULT;
                if (len < *lenp) {
                        if(put_user('\n', ((char __user *) buffer) + len))
@@ -1691,12 +1720,38 @@ int proc_dostring(ctl_table *table, int write, struct file *filp,
        return 0;
 }
 
+/**
+ * proc_dostring - read a string sysctl
+ * @table: the sysctl table
+ * @write: %TRUE if this is a write to the sysctl file
+ * @filp: the file structure
+ * @buffer: the user buffer
+ * @lenp: the size of the user buffer
+ * @ppos: file position
+ *
+ * Reads/writes a string from/to the user buffer. If the kernel
+ * buffer provided is not large enough to hold the string, the
+ * string is truncated. The copied string is %NULL-terminated.
+ * If the string is being read by the user process, it is copied
+ * and a newline '\n' is added. It is truncated if the buffer is
+ * not large enough.
+ *
+ * Returns 0 on success.
+ */
+int proc_dostring(ctl_table *table, int write, struct file *filp,
+                 void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+       return _proc_do_string(table->data, table->maxlen, write, filp,
+                              buffer, lenp, ppos);
+}
+
 /*
  *     Special case of dostring for the UTS structure. This has locks
  *     to observe. Should this be in kernel/sys.c ????
  */
  
-static int proc_doutsstring(ctl_table *table, int write, struct file *filp,
+#ifndef CONFIG_UTS_NS
+static int proc_do_uts_string(ctl_table *table, int write, struct file *filp,
                  void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        int r;
@@ -1712,6 +1767,48 @@ static int proc_doutsstring(ctl_table *table, int write, struct file *filp,
        }
        return r;
 }
+#else /* !CONFIG_UTS_NS */
+static int proc_do_uts_string(ctl_table *table, int write, struct file *filp,
+                 void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+       int r;
+       struct uts_namespace* uts_ns = current->nsproxy->uts_ns;
+       char* which;
+
+       switch (table->ctl_name) {
+       case KERN_OSTYPE:
+               which = uts_ns->name.sysname;
+               break;
+       case KERN_NODENAME:
+               which = uts_ns->name.nodename;
+               break;
+       case KERN_OSRELEASE:
+               which = uts_ns->name.release;
+               break;
+       case KERN_VERSION:
+               which = uts_ns->name.version;
+               break;
+       case KERN_DOMAINNAME:
+               which = uts_ns->name.domainname;
+               break;
+       default:
+               r = -EINVAL;
+               goto out;
+       }
+
+       if (!write) {
+               down_read(&uts_sem);
+               r=_proc_do_string(which,table->maxlen,0,filp,buffer,lenp, ppos);
+               up_read(&uts_sem);
+       } else {
+               down_write(&uts_sem);
+               r=_proc_do_string(which,table->maxlen,1,filp,buffer,lenp, ppos);
+               up_write(&uts_sem);
+       }
+ out:
+       return r;
+}
+#endif /* !CONFIG_UTS_NS */
 
 static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp,
                                 int *valp,
@@ -1732,8 +1829,9 @@ static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp,
        return 0;
 }
 
-static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
-                 void __user *buffer, size_t *lenp, loff_t *ppos,
+static int __do_proc_dointvec(void *tbl_data, ctl_table *table,
+                 int write, struct file *filp, void __user *buffer,
+                 size_t *lenp, loff_t *ppos,
                  int (*conv)(int *negp, unsigned long *lvalp, int *valp,
                              int write, void *data),
                  void *data)
@@ -1746,13 +1844,13 @@ static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
        char buf[TMPBUFLEN], *p;
        char __user *s = buffer;
        
-       if (!table->data || !table->maxlen || !*lenp ||
+       if (!tbl_data || !table->maxlen || !*lenp ||
            (*ppos && !write)) {
                *lenp = 0;
                return 0;
        }
        
-       i = (int *) table->data;
+       i = (int *) tbl_data;
        vleft = table->maxlen / sizeof(*i);
        left = *lenp;
 
@@ -1841,6 +1939,16 @@ static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
 #undef TMPBUFLEN
 }
 
+static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
+                 void __user *buffer, size_t *lenp, loff_t *ppos,
+                 int (*conv)(int *negp, unsigned long *lvalp, int *valp,
+                             int write, void *data),
+                 void *data)
+{
+       return __do_proc_dointvec(table->data, table, write, filp,
+                       buffer, lenp, ppos, conv, data);
+}
+
 /**
  * proc_dointvec - read a vector of integers
  * @table: the sysctl table
@@ -1974,7 +2082,7 @@ int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
                                do_proc_dointvec_minmax_conv, &param);
 }
 
-static int do_proc_doulongvec_minmax(ctl_table *table, int write,
+static int __do_proc_doulongvec_minmax(void *data, ctl_table *table, int write,
                                     struct file *filp,
                                     void __user *buffer,
                                     size_t *lenp, loff_t *ppos,
@@ -1988,13 +2096,13 @@ static int do_proc_doulongvec_minmax(ctl_table *table, int write,
        char buf[TMPBUFLEN], *p;
        char __user *s = buffer;
        
-       if (!table->data || !table->maxlen || !*lenp ||
+       if (!data || !table->maxlen || !*lenp ||
            (*ppos && !write)) {
                *lenp = 0;
                return 0;
        }
        
-       i = (unsigned long *) table->data;
+       i = (unsigned long *) data;
        min = (unsigned long *) table->extra1;
        max = (unsigned long *) table->extra2;
        vleft = table->maxlen / sizeof(unsigned long);
@@ -2079,6 +2187,17 @@ static int do_proc_doulongvec_minmax(ctl_table *table, int write,
 #undef TMPBUFLEN
 }
 
+static int do_proc_doulongvec_minmax(ctl_table *table, int write,
+                                    struct file *filp,
+                                    void __user *buffer,
+                                    size_t *lenp, loff_t *ppos,
+                                    unsigned long convmul,
+                                    unsigned long convdiv)
+{
+       return __do_proc_doulongvec_minmax(table->data, table, write,
+                       filp, buffer, lenp, ppos, convmul, convdiv);
+}
+
 /**
  * proc_doulongvec_minmax - read a vector of long integers with min/max values
  * @table: the sysctl table
@@ -2267,6 +2386,71 @@ int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp,
                                do_proc_dointvec_ms_jiffies_conv, NULL);
 }
 
+#ifdef CONFIG_SYSVIPC
+static int proc_do_ipc_string(ctl_table *table, int write, struct file *filp,
+               void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+       void *data;
+       struct ipc_namespace *ns;
+
+       ns = current->nsproxy->ipc_ns;
+
+       switch (table->ctl_name) {
+       case KERN_SHMMAX:
+               data = &ns->shm_ctlmax;
+               goto proc_minmax;
+       case KERN_SHMALL:
+               data = &ns->shm_ctlall;
+               goto proc_minmax;
+       case KERN_SHMMNI:
+               data = &ns->shm_ctlmni;
+               break;
+       case KERN_MSGMAX:
+               data = &ns->msg_ctlmax;
+               break;
+       case KERN_MSGMNI:
+               data = &ns->msg_ctlmni;
+               break;
+       case KERN_MSGMNB:
+               data = &ns->msg_ctlmnb;
+               break;
+       case KERN_SEM:
+               data = &ns->sem_ctls;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return __do_proc_dointvec(data, table, write, filp, buffer,
+                       lenp, ppos, NULL, NULL);
+proc_minmax:
+       return __do_proc_doulongvec_minmax(data, table, write, filp, buffer,
+                       lenp, ppos, 1l, 1l);
+}
+#endif
+
+static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
+                          void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+       struct pid *new_pid;
+       pid_t tmp;
+       int r;
+
+       tmp = pid_nr(cad_pid);
+
+       r = __do_proc_dointvec(&tmp, table, write, filp, buffer,
+                              lenp, ppos, NULL, NULL);
+       if (r || !write)
+               return r;
+
+       new_pid = find_get_pid(tmp);
+       if (!new_pid)
+               return -ESRCH;
+
+       put_pid(xchg(&cad_pid, new_pid));
+       return 0;
+}
+
 #else /* CONFIG_PROC_FS */
 
 int proc_dostring(ctl_table *table, int write, struct file *filp,
@@ -2275,12 +2459,20 @@ int proc_dostring(ctl_table *table, int write, struct file *filp,
        return -ENOSYS;
 }
 
-static int proc_doutsstring(ctl_table *table, int write, struct file *filp,
-                           void __user *buffer, size_t *lenp, loff_t *ppos)
+static int proc_do_uts_string(ctl_table *table, int write, struct file *filp,
+               void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        return -ENOSYS;
 }
 
+#ifdef CONFIG_SYSVIPC
+static int proc_do_ipc_string(ctl_table *table, int write, struct file *filp,
+               void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+       return -ENOSYS;
+}
+#endif
+
 int proc_dointvec(ctl_table *table, int write, struct file *filp,
                  void __user *buffer, size_t *lenp, loff_t *ppos)
 {
diff --git a/kernel/utsname.c b/kernel/utsname.c
new file mode 100644 (file)
index 0000000..c859164
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ *  Copyright (C) 2004 IBM Corporation
+ *
+ *  Author: Serge Hallyn <serue@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, version 2 of the
+ *  License.
+ */
+
+#include <linux/module.h>
+#include <linux/uts.h>
+#include <linux/utsname.h>
+#include <linux/version.h>
+
+/*
+ * Clone a new ns copying an original utsname, setting refcount to 1
+ * @old_ns: namespace to clone
+ * Return NULL on error (failure to kmalloc), new ns otherwise
+ */
+static struct uts_namespace *clone_uts_ns(struct uts_namespace *old_ns)
+{
+       struct uts_namespace *ns;
+
+       ns = kmalloc(sizeof(struct uts_namespace), GFP_KERNEL);
+       if (ns) {
+               memcpy(&ns->name, &old_ns->name, sizeof(ns->name));
+               kref_init(&ns->kref);
+       }
+       return ns;
+}
+
+/*
+ * unshare the current process' utsname namespace.
+ * called only in sys_unshare()
+ */
+int unshare_utsname(unsigned long unshare_flags, struct uts_namespace **new_uts)
+{
+       if (unshare_flags & CLONE_NEWUTS) {
+               if (!capable(CAP_SYS_ADMIN))
+                       return -EPERM;
+
+               *new_uts = clone_uts_ns(current->nsproxy->uts_ns);
+               if (!*new_uts)
+                       return -ENOMEM;
+       }
+
+       return 0;
+}
+
+/*
+ * Copy task tsk's utsname namespace, or clone it if flags
+ * specifies CLONE_NEWUTS.  In latter case, changes to the
+ * utsname of this process won't be seen by parent, and vice
+ * versa.
+ */
+int copy_utsname(int flags, struct task_struct *tsk)
+{
+       struct uts_namespace *old_ns = tsk->nsproxy->uts_ns;
+       struct uts_namespace *new_ns;
+       int err = 0;
+
+       if (!old_ns)
+               return 0;
+
+       get_uts_ns(old_ns);
+
+       if (!(flags & CLONE_NEWUTS))
+               return 0;
+
+       if (!capable(CAP_SYS_ADMIN)) {
+               err = -EPERM;
+               goto out;
+       }
+
+       new_ns = clone_uts_ns(old_ns);
+       if (!new_ns) {
+               err = -ENOMEM;
+               goto out;
+       }
+       tsk->nsproxy->uts_ns = new_ns;
+
+out:
+       put_uts_ns(old_ns);
+       return err;
+}
+
+void free_uts_ns(struct kref *kref)
+{
+       struct uts_namespace *ns;
+
+       ns = container_of(kref, struct uts_namespace, kref);
+       kfree(ns);
+}
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 f9ae75cc014566b95609983b803e0ef6282723f8..756a908c441d28710e773e15b7b619191f9efdcd 100644 (file)
@@ -384,3 +384,17 @@ config RCU_TORTURE_TEST
          at boot time (you probably don't).
          Say M if you want the RCU torture tests to build as a module.
          Say N if you are unsure.
+
+config LKDTM
+       tristate "Linux Kernel Dump Test Tool Module"
+       depends on KPROBES
+       default n
+       help
+       This module enables testing of the different dumping mechanisms by
+       inducing system failures at predefined crash points.
+       If you don't need it: say N
+       Choose M here to compile this code as a module. The module will be
+       called lkdtm.
+
+       Documentation on how to use the module can be found in
+       drivers/misc/lkdtm.c
index ddf3e676e1f47b1b18f8cc62ea31f17724e021f6..b0361756e22e2ff0801a12e4291b7d51a22305a8 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for some libs needed in the kernel.
 #
 
-lib-y := errno.o ctype.o string.o vsprintf.o cmdline.o \
+lib-y := ctype.o string.o vsprintf.o cmdline.o \
         bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \
         idr.o div64.o int_sqrt.o bitmap.o extable.o prio_tree.o \
         sha1.o
index 3a67dc5ada7d5b2655ae461890519e995d50d7c9..7a2a73f88d594dc73282c24e3d0304a602a10a25 100644 (file)
@@ -43,3 +43,19 @@ int __any_online_cpu(const cpumask_t *mask)
        return cpu;
 }
 EXPORT_SYMBOL(__any_online_cpu);
+
+#if MAX_NUMNODES > 1
+/*
+ * Find the highest possible node id.
+ */
+int highest_possible_node_id(void)
+{
+       unsigned int node;
+       unsigned int highest = 0;
+
+       for_each_node_mask(node, node_possible_map)
+               highest = node;
+       return highest;
+}
+EXPORT_SYMBOL(highest_possible_node_id);
+#endif
diff --git a/lib/errno.c b/lib/errno.c
deleted file mode 100644 (file)
index 41cb9d7..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- *  linux/lib/errno.c
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- */
-
-int errno;
index 71338b48e88919ab2a668ecf2ff9f1e25a91b0fa..75ae68ce03e10be0596a1a86956360bf9fc012bb 100644 (file)
 #include <linux/genalloc.h>
 
 
-/*
- * Create a new special memory pool.
- *
+/**
+ * gen_pool_create - create a new special memory pool
  * @min_alloc_order: log base 2 of number of bytes each bitmap bit represents
  * @nid: node id of the node the pool structure should be allocated on, or -1
+ *
+ * Create a new special memory pool that can be used to manage special purpose
+ * memory not managed by the regular kmalloc/kfree interface.
  */
 struct gen_pool *gen_pool_create(int min_alloc_order, int nid)
 {
@@ -34,15 +36,15 @@ struct gen_pool *gen_pool_create(int min_alloc_order, int nid)
 }
 EXPORT_SYMBOL(gen_pool_create);
 
-
-/*
- * Add a new chunk of memory to the specified pool.
- *
+/**
+ * gen_pool_add - add a new chunk of special memory to the pool
  * @pool: pool to add new memory chunk to
  * @addr: starting address of memory chunk to add to pool
  * @size: size in bytes of the memory chunk to add to pool
  * @nid: node id of the node the chunk structure and bitmap should be
  *       allocated on, or -1
+ *
+ * Add a new chunk of special memory to the specified pool.
  */
 int gen_pool_add(struct gen_pool *pool, unsigned long addr, size_t size,
                 int nid)
@@ -69,13 +71,44 @@ int gen_pool_add(struct gen_pool *pool, unsigned long addr, size_t size,
 }
 EXPORT_SYMBOL(gen_pool_add);
 
-
-/*
- * Allocate the requested number of bytes from the specified pool.
- * Uses a first-fit algorithm.
+/**
+ * gen_pool_destroy - destroy a special memory pool
+ * @pool: pool to destroy
  *
+ * Destroy the specified special memory pool. Verifies that there are no
+ * outstanding allocations.
+ */
+void gen_pool_destroy(struct gen_pool *pool)
+{
+       struct list_head *_chunk, *_next_chunk;
+       struct gen_pool_chunk *chunk;
+       int order = pool->min_alloc_order;
+       int bit, end_bit;
+
+
+       write_lock(&pool->lock);
+       list_for_each_safe(_chunk, _next_chunk, &pool->chunks) {
+               chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk);
+               list_del(&chunk->next_chunk);
+
+               end_bit = (chunk->end_addr - chunk->start_addr) >> order;
+               bit = find_next_bit(chunk->bits, end_bit, 0);
+               BUG_ON(bit < end_bit);
+
+               kfree(chunk);
+       }
+       kfree(pool);
+       return;
+}
+EXPORT_SYMBOL(gen_pool_destroy);
+
+/**
+ * gen_pool_alloc - allocate special memory from the pool
  * @pool: pool to allocate from
  * @size: number of bytes to allocate from the pool
+ *
+ * Allocate the requested number of bytes from the specified pool.
+ * Uses a first-fit algorithm.
  */
 unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size)
 {
@@ -127,13 +160,13 @@ unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size)
 }
 EXPORT_SYMBOL(gen_pool_alloc);
 
-
-/*
- * Free the specified memory back to the specified pool.
- *
+/**
+ * gen_pool_free - free allocated special memory back to the pool
  * @pool: pool to free to
  * @addr: starting address of memory to free back to pool
  * @size: size in bytes of memory to free
+ *
+ * Free previously allocated special memory back to the specified pool.
  */
 void gen_pool_free(struct gen_pool *pool, unsigned long addr, size_t size)
 {
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 5f3b51ffa1dc2a6897b09b42cee81ef2870b9ec8..488788b341cb01960b92163b9326ec85c2a33445 100644 (file)
@@ -49,15 +49,15 @@ void sort(void *base, size_t num, size_t size,
          void (*swap)(void *, void *, int size))
 {
        /* pre-scale counters for performance */
-       int i = (num/2) * size, n = num * size, c, r;
+       int i = (num/2 - 1) * size, n = num * size, c, r;
 
        if (!swap)
                swap = (size == 4 ? u32_swap : generic_swap);
 
        /* heapify */
        for ( ; i >= 0; i -= size) {
-               for (r = i; r * 2 < n; r  = c) {
-                       c = r * 2;
+               for (r = i; r * 2 + size < n; r  = c) {
+                       c = r * 2 + size;
                        if (c < n - size && cmp(base + c, base + c + size) < 0)
                                c += size;
                        if (cmp(base + r, base + c) >= 0)
@@ -69,8 +69,8 @@ void sort(void *base, size_t num, size_t size,
        /* sort */
        for (i = n - size; i >= 0; i -= size) {
                swap(base, base + i, size);
-               for (r = 0; r * 2 < i; r = c) {
-                       c = r * 2;
+               for (r = 0; r * 2 + size < i; r = c) {
+                       c = r * 2 + size;
                        if (c < i - size && cmp(base + c, base + c + size) < 0)
                                c += size;
                        if (cmp(base + r, base + c) >= 0)
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 fef7d879ddf5f2cb30eae36ee7e7a74fc1cc806f..3464b681f8449eda37ee74b9581ad03266f6e619 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 26f322737db0c83702267b25190dca8fa925c324..1958ad1b8541e57be7f32bb70b2b19a242884dce 100644 (file)
@@ -1011,7 +1011,7 @@ static int rfcomm_tty_tiocmset(struct tty_struct *tty, struct file *filp, unsign
 
 /* ---- TTY structure ---- */
 
-static struct tty_operations rfcomm_ops = {
+static const struct tty_operations rfcomm_ops = {
        .open                   = rfcomm_tty_open,
        .close                  = rfcomm_tty_close,
        .write                  = rfcomm_tty_write,
index 770c0df972a3bfcb2d0f208ac0dfbd024db1b77e..b54306a934e58196af7c136a9d27d050adeff7df 100644 (file)
@@ -22,24 +22,37 @@ static int ebt_target_mark(struct sk_buff **pskb, unsigned int hooknr,
    const void *data, unsigned int datalen)
 {
        struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)data;
+       int action = info->target & -16;
 
-       if ((*pskb)->nfmark != info->mark)
+       if (action == MARK_SET_VALUE)
                (*pskb)->nfmark = info->mark;
+       else if (action == MARK_OR_VALUE)
+               (*pskb)->nfmark |= info->mark;
+       else if (action == MARK_AND_VALUE)
+               (*pskb)->nfmark &= info->mark;
+       else
+               (*pskb)->nfmark ^= info->mark;
 
-       return info->target;
+       return info->target | -16;
 }
 
 static int ebt_target_mark_check(const char *tablename, unsigned int hookmask,
    const struct ebt_entry *e, void *data, unsigned int datalen)
 {
        struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)data;
+       int tmp;
 
        if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_t_info)))
                return -EINVAL;
-       if (BASE_CHAIN && info->target == EBT_RETURN)
+       tmp = info->target | -16;
+       if (BASE_CHAIN && tmp == EBT_RETURN)
                return -EINVAL;
        CLEAR_BASE_CHAIN_BIT;
-       if (INVALID_TARGET)
+       if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
+               return -EINVAL;
+       tmp = info->target & -16;
+       if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE &&
+           tmp != MARK_AND_VALUE && tmp != MARK_XOR_VALUE)
                return -EINVAL;
        return 0;
 }
index 8ce8c471d8687427ad2b88acf5d33a17a874bbbc..b4b478353b27e520db99a304f5e187e836bd223f 100644 (file)
@@ -344,12 +344,12 @@ struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
 {
        struct neighbour *n;
        int key_len = tbl->key_len;
-       u32 hash_val = tbl->hash(pkey, dev) & tbl->hash_mask;
+       u32 hash_val = tbl->hash(pkey, dev);
        
        NEIGH_CACHE_STAT_INC(tbl, lookups);
 
        read_lock_bh(&tbl->lock);
-       for (n = tbl->hash_buckets[hash_val]; n; n = n->next) {
+       for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) {
                if (dev == n->dev && !memcmp(n->primary_key, pkey, key_len)) {
                        neigh_hold(n);
                        NEIGH_CACHE_STAT_INC(tbl, hits);
@@ -364,12 +364,12 @@ struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, const void *pkey)
 {
        struct neighbour *n;
        int key_len = tbl->key_len;
-       u32 hash_val = tbl->hash(pkey, NULL) & tbl->hash_mask;
+       u32 hash_val = tbl->hash(pkey, NULL);
 
        NEIGH_CACHE_STAT_INC(tbl, lookups);
 
        read_lock_bh(&tbl->lock);
-       for (n = tbl->hash_buckets[hash_val]; n; n = n->next) {
+       for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) {
                if (!memcmp(n->primary_key, pkey, key_len)) {
                        neigh_hold(n);
                        NEIGH_CACHE_STAT_INC(tbl, hits);
@@ -1998,12 +1998,12 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
        int rc, h, s_h = cb->args[1];
        int idx, s_idx = idx = cb->args[2];
 
+       read_lock_bh(&tbl->lock);
        for (h = 0; h <= tbl->hash_mask; h++) {
                if (h < s_h)
                        continue;
                if (h > s_h)
                        s_idx = 0;
-               read_lock_bh(&tbl->lock);
                for (n = tbl->hash_buckets[h], idx = 0; n; n = n->next, idx++) {
                        if (idx < s_idx)
                                continue;
@@ -2016,8 +2016,8 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
                                goto out;
                        }
                }
-               read_unlock_bh(&tbl->lock);
        }
+       read_unlock_bh(&tbl->lock);
        rc = skb->len;
 out:
        cb->args[1] = h;
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..5572071af735ea7716143752bfad35ea969e65b6 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.
 
@@ -434,6 +434,15 @@ config INET_XFRM_MODE_TUNNEL
 
          If unsure, say Y.
 
+config INET_XFRM_MODE_BEET
+       tristate "IP: IPsec BEET mode"
+       default y
+       select XFRM
+       ---help---
+         Support for IPsec BEET mode.
+
+         If unsure, say Y.
+
 config INET_DIAG
        tristate "INET: socket monitoring interface"
        default y
@@ -526,7 +535,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 +565,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 f66049e28aebba92a946b92bb0339b35e15b5aee..15645c51520cc4cbec7599fbe9676a9f68e6a115 100644 (file)
@@ -23,6 +23,7 @@ obj-$(CONFIG_INET_AH) += ah4.o
 obj-$(CONFIG_INET_ESP) += esp4.o
 obj-$(CONFIG_INET_IPCOMP) += ipcomp.o
 obj-$(CONFIG_INET_XFRM_TUNNEL) += xfrm4_tunnel.o
+obj-$(CONFIG_INET_XFRM_MODE_BEET) += xfrm4_mode_beet.o
 obj-$(CONFIG_INET_TUNNEL) += tunnel4.o
 obj-$(CONFIG_INET_XFRM_MODE_TRANSPORT) += xfrm4_mode_transport.o
 obj-$(CONFIG_INET_XFRM_MODE_TUNNEL) += xfrm4_mode_tunnel.o
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 13b29360d102f1c463fce57d4d24992a6117ba27..b5c205b57669823d55449c8a98ae673b870fd1d5 100644 (file)
@@ -253,7 +253,8 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
                 *    as per draft-ietf-ipsec-udp-encaps-06,
                 *    section 3.1.2
                 */
-               if (x->props.mode == XFRM_MODE_TRANSPORT)
+               if (x->props.mode == XFRM_MODE_TRANSPORT ||
+                   x->props.mode == XFRM_MODE_BEET)
                        skb->ip_summed = CHECKSUM_UNNECESSARY;
        }
 
@@ -271,17 +272,28 @@ static u32 esp4_get_max_size(struct xfrm_state *x, int mtu)
 {
        struct esp_data *esp = x->data;
        u32 blksize = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4);
-
-       if (x->props.mode == XFRM_MODE_TUNNEL) {
-               mtu = ALIGN(mtu + 2, blksize);
-       } else {
-               /* The worst case. */
+       int enclen = 0;
+
+       switch (x->props.mode) {
+       case XFRM_MODE_TUNNEL:
+               mtu = ALIGN(mtu +2, blksize);
+               break;
+       default:
+       case XFRM_MODE_TRANSPORT:
+               /* The worst case */
                mtu = ALIGN(mtu + 2, 4) + blksize - 4;
+               break;
+       case XFRM_MODE_BEET:
+               /* The worst case. */
+               enclen = IPV4_BEET_PHMAXLEN;
+               mtu = ALIGN(mtu + enclen + 2, blksize);
+               break;
        }
+
        if (esp->conf.padlen)
                mtu = ALIGN(mtu, esp->conf.padlen);
 
-       return mtu + x->props.header_len + esp->auth.icv_trunc_len;
+       return mtu + x->props.header_len + esp->auth.icv_trunc_len - enclen;
 }
 
 static void esp4_err(struct sk_buff *skb, u32 info)
index 2017d36024d48d61816bd52e82bf67f4c196479d..3839b706142e3816f73bbc9a6ff361a9f8467d44 100644 (file)
@@ -206,6 +206,7 @@ static void ipcomp4_err(struct sk_buff *skb, u32 info)
 static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x)
 {
        struct xfrm_state *t;
+       u8 mode = XFRM_MODE_TUNNEL;
        
        t = xfrm_state_alloc();
        if (t == NULL)
@@ -216,7 +217,9 @@ static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x)
        t->id.daddr.a4 = x->id.daddr.a4;
        memcpy(&t->sel, &x->sel, sizeof(t->sel));
        t->props.family = AF_INET;
-       t->props.mode = XFRM_MODE_TUNNEL;
+       if (x->props.mode == XFRM_MODE_BEET)
+               mode = x->props.mode;
+       t->props.mode = mode;
        t->props.saddr.a4 = x->props.saddr.a4;
        t->props.flags = x->props.flags;
 
index 1fbb38415b193e66f487a5eb8aef1738df866661..f8ce8475915966c7d10abbec1542f71b1ac10d0d 100644 (file)
@@ -366,7 +366,7 @@ static int __init ic_defaults(void)
         */
         
        if (!ic_host_name_set)
-               sprintf(system_utsname.nodename, "%u.%u.%u.%u", NIPQUAD(ic_myaddr));
+               sprintf(init_utsname()->nodename, "%u.%u.%u.%u", NIPQUAD(ic_myaddr));
 
        if (root_server_addr == INADDR_NONE)
                root_server_addr = ic_servaddr;
@@ -805,7 +805,7 @@ static void __init ic_do_bootp_ext(u8 *ext)
                        }
                        break;
                case 12:        /* Host name */
-                       ic_bootp_string(system_utsname.nodename, ext+1, *ext, __NEW_UTS_LEN);
+                       ic_bootp_string(utsname()->nodename, ext+1, *ext, __NEW_UTS_LEN);
                        ic_host_name_set = 1;
                        break;
                case 15:        /* Domain name (DNS) */
@@ -816,7 +816,7 @@ static void __init ic_do_bootp_ext(u8 *ext)
                                ic_bootp_string(root_server_path, ext+1, *ext, sizeof(root_server_path));
                        break;
                case 40:        /* NIS Domain name (_not_ DNS) */
-                       ic_bootp_string(system_utsname.domainname, ext+1, *ext, __NEW_UTS_LEN);
+                       ic_bootp_string(utsname()->domainname, ext+1, *ext, __NEW_UTS_LEN);
                        break;
        }
 }
@@ -1368,7 +1368,7 @@ static int __init ip_auto_config(void)
        printk(", mask=%u.%u.%u.%u", NIPQUAD(ic_netmask));
        printk(", gw=%u.%u.%u.%u", NIPQUAD(ic_gateway));
        printk(",\n     host=%s, domain=%s, nis-domain=%s",
-              system_utsname.nodename, ic_domain, system_utsname.domainname);
+              utsname()->nodename, ic_domain, utsname()->domainname);
        printk(",\n     bootserver=%u.%u.%u.%u", NIPQUAD(ic_servaddr));
        printk(", rootserver=%u.%u.%u.%u", NIPQUAD(root_server_addr));
        printk(", rootpath=%s", root_server_path);
@@ -1478,11 +1478,11 @@ static int __init ip_auto_config_setup(char *addrs)
                        case 4:
                                if ((dp = strchr(ip, '.'))) {
                                        *dp++ = '\0';
-                                       strlcpy(system_utsname.domainname, dp,
-                                               sizeof(system_utsname.domainname));
+                                       strlcpy(utsname()->domainname, dp,
+                                               sizeof(utsname()->domainname));
                                }
-                               strlcpy(system_utsname.nodename, ip,
-                                       sizeof(system_utsname.nodename));
+                               strlcpy(utsname()->nodename, ip,
+                                       sizeof(utsname()->nodename));
                                ic_host_name_set = 1;
                                break;
                        case 5:
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 6dee03935f786076448f7f1573abc2c806ff12f0..1445bb47fea4bcb6264a6b48de8cc7a4632e671b 100644 (file)
@@ -813,6 +813,16 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb,
        skb->nh.iph->saddr = cp->vaddr;
        ip_send_check(skb->nh.iph);
 
+       /* For policy routing, packets originating from this
+        * machine itself may be routed differently to packets
+        * passing through.  We want this packet to be routed as
+        * if it came from this machine itself.  So re-compute
+        * the routing information.
+        */
+       if (ip_route_me_harder(pskb, RTN_LOCAL) != 0)
+               goto drop;
+       skb = *pskb;
+
        IP_VS_DBG_PKT(10, pp, skb, 0, "After SNAT");
 
        ip_vs_out_stats(cp, skb);
index 5ac15379a0cfd15d76c0f7c06145d8da58ba6049..e2005c6810a4e39a0765cac968adb0362645e3fb 100644 (file)
@@ -8,7 +8,7 @@
 #include <net/ip.h>
 
 /* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */
-int ip_route_me_harder(struct sk_buff **pskb)
+int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type)
 {
        struct iphdr *iph = (*pskb)->nh.iph;
        struct rtable *rt;
@@ -16,10 +16,13 @@ int ip_route_me_harder(struct sk_buff **pskb)
        struct dst_entry *odst;
        unsigned int hh_len;
 
+       if (addr_type == RTN_UNSPEC)
+               addr_type = inet_addr_type(iph->saddr);
+
        /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause
         * packets with foreign saddr to appear on the NF_IP_LOCAL_OUT hook.
         */
-       if (inet_addr_type(iph->saddr) == RTN_LOCAL) {
+       if (addr_type == RTN_LOCAL) {
                fl.nl_u.ip4_u.daddr = iph->daddr;
                fl.nl_u.ip4_u.saddr = iph->saddr;
                fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
@@ -156,7 +159,7 @@ static int nf_ip_reroute(struct sk_buff **pskb, const struct nf_info *info)
                if (!(iph->tos == rt_info->tos
                      && iph->daddr == rt_info->daddr
                      && iph->saddr == rt_info->saddr))
-                       return ip_route_me_harder(pskb);
+                       return ip_route_me_harder(pskb, RTN_UNSPEC);
        }
        return 0;
 }
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 021395b674639b19f65975732239321a2fd34750..d85d2de504497dc2102fe3d497247e70ec277df7 100644 (file)
@@ -265,7 +265,8 @@ ip_nat_local_fn(unsigned int hooknum,
                       ct->tuplehash[!dir].tuple.src.u.all
 #endif
                    )
-                       return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
+                       if (ip_route_me_harder(pskb, RTN_UNSPEC))
+                               ret = NF_DROP;
        }
        return ret;
 }
index fd0c05efed8a088ead0dc29ca1e08a05147a9e22..ad0312d0e4fd6a214c4ab1dc232268e9c2b52949 100644 (file)
@@ -38,76 +38,16 @@ MODULE_DESCRIPTION("iptables REJECT target module");
 #define DEBUGP(format, args...)
 #endif
 
-static inline struct rtable *route_reverse(struct sk_buff *skb, 
-                                          struct tcphdr *tcph, int hook)
-{
-       struct iphdr *iph = skb->nh.iph;
-       struct dst_entry *odst;
-       struct flowi fl = {};
-       struct rtable *rt;
-
-       /* We don't require ip forwarding to be enabled to be able to
-        * send a RST reply for bridged traffic. */
-       if (hook != NF_IP_FORWARD
-#ifdef CONFIG_BRIDGE_NETFILTER
-           || (skb->nf_bridge && skb->nf_bridge->mask & BRNF_BRIDGED)
-#endif
-          ) {
-               fl.nl_u.ip4_u.daddr = iph->saddr;
-               if (hook == NF_IP_LOCAL_IN)
-                       fl.nl_u.ip4_u.saddr = iph->daddr;
-               fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
-
-               if (ip_route_output_key(&rt, &fl) != 0)
-                       return NULL;
-       } else {
-               /* non-local src, find valid iif to satisfy
-                * rp-filter when calling ip_route_input. */
-               fl.nl_u.ip4_u.daddr = iph->daddr;
-               if (ip_route_output_key(&rt, &fl) != 0)
-                       return NULL;
-
-               odst = skb->dst;
-               if (ip_route_input(skb, iph->saddr, iph->daddr,
-                                  RT_TOS(iph->tos), rt->u.dst.dev) != 0) {
-                       dst_release(&rt->u.dst);
-                       return NULL;
-               }
-               dst_release(&rt->u.dst);
-               rt = (struct rtable *)skb->dst;
-               skb->dst = odst;
-
-               fl.nl_u.ip4_u.daddr = iph->saddr;
-               fl.nl_u.ip4_u.saddr = iph->daddr;
-               fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
-       }
-
-       if (rt->u.dst.error) {
-               dst_release(&rt->u.dst);
-               return NULL;
-       }
-
-       fl.proto = IPPROTO_TCP;
-       fl.fl_ip_sport = tcph->dest;
-       fl.fl_ip_dport = tcph->source;
-       security_skb_classify_flow(skb, &fl);
-
-       xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0);
-
-       return rt;
-}
-
 /* Send RST reply */
 static void send_reset(struct sk_buff *oldskb, int hook)
 {
        struct sk_buff *nskb;
        struct iphdr *iph = oldskb->nh.iph;
        struct tcphdr _otcph, *oth, *tcph;
-       struct rtable *rt;
        __be16 tmp_port;
        __be32 tmp_addr;
        int needs_ack;
-       int hh_len;
+       unsigned int addr_type;
 
        /* IP header checks: fragment. */
        if (oldskb->nh.iph->frag_off & htons(IP_OFFSET))
@@ -126,23 +66,13 @@ static void send_reset(struct sk_buff *oldskb, int hook)
        if (nf_ip_checksum(oldskb, hook, iph->ihl * 4, IPPROTO_TCP))
                return;
 
-       if ((rt = route_reverse(oldskb, oth, hook)) == NULL)
-               return;
-
-       hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
-
        /* We need a linear, writeable skb.  We also need to expand
           headroom in case hh_len of incoming interface < hh_len of
           outgoing interface */
-       nskb = skb_copy_expand(oldskb, hh_len, skb_tailroom(oldskb),
+       nskb = skb_copy_expand(oldskb, LL_MAX_HEADER, skb_tailroom(oldskb),
                               GFP_ATOMIC);
-       if (!nskb) {
-               dst_release(&rt->u.dst);
+       if (!nskb)
                return;
-       }
-
-       dst_release(nskb->dst);
-       nskb->dst = &rt->u.dst;
 
        /* This packet will not be the same as the other: clear nf fields */
        nf_reset(nskb);
@@ -184,6 +114,21 @@ static void send_reset(struct sk_buff *oldskb, int hook)
        tcph->window = 0;
        tcph->urg_ptr = 0;
 
+       /* Set DF, id = 0 */
+       nskb->nh.iph->frag_off = htons(IP_DF);
+       nskb->nh.iph->id = 0;
+
+       addr_type = RTN_UNSPEC;
+       if (hook != NF_IP_FORWARD
+#ifdef CONFIG_BRIDGE_NETFILTER
+           || (nskb->nf_bridge && nskb->nf_bridge->mask & BRNF_BRIDGED)
+#endif
+          )
+               addr_type = RTN_LOCAL;
+
+       if (ip_route_me_harder(&nskb, addr_type))
+               goto free_nskb;
+
        /* Adjust TCP checksum */
        nskb->ip_summed = CHECKSUM_NONE;
        tcph->check = 0;
@@ -192,12 +137,8 @@ static void send_reset(struct sk_buff *oldskb, int hook)
                                   nskb->nh.iph->daddr,
                                   csum_partial((char *)tcph,
                                                sizeof(struct tcphdr), 0));
-
-       /* Adjust IP TTL, DF */
+       /* Adjust IP TTL */
        nskb->nh.iph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);
-       /* Set DF, id = 0 */
-       nskb->nh.iph->frag_off = htons(IP_DF);
-       nskb->nh.iph->id = 0;
 
        /* Adjust IP checksum */
        nskb->nh.iph->check = 0;
index e62ea2bb9c0ac422f7c77e39aa7f99eba5fa6e3b..b91f3582359bf3aad31681e4c5d0f1e95c1bb4e6 100644 (file)
@@ -157,7 +157,8 @@ ipt_local_hook(unsigned int hook,
                || (*pskb)->nfmark != nfmark
 #endif
                || (*pskb)->nh.iph->tos != tos))
-               return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
+               if (ip_route_me_harder(pskb, RTN_UNSPEC))
+                       ret = NF_DROP;
 
        return ret;
 }
index 3f884cea14ff439651b876ffce4f351289640681..cf06accbe687a96a21bf5098163b4c8ddb662818 100644 (file)
@@ -2259,7 +2259,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
        u32 pkts_acked = 0;
        void (*rtt_sample)(struct sock *sk, u32 usrtt)
                = icsk->icsk_ca_ops->rtt_sample;
-       struct timeval tv;
+       struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
 
        while ((skb = skb_peek(&sk->sk_write_queue)) &&
               skb != sk->sk_send_head) {
index dab37d2f65fcf09a820bce52300d7f335ab5066c..4be336f17883ca21e129fd93a146d6e73c338fb1 100644 (file)
@@ -99,8 +99,10 @@ static int jtcp_sendmsg(struct kiocb *iocb, struct sock *sk,
 }
 
 static struct jprobe tcp_send_probe = {
-       .kp = { .addr = (kprobe_opcode_t *) &tcp_sendmsg, },
-       .entry = (kprobe_opcode_t *) &jtcp_sendmsg,
+       .kp = {
+               .symbol_name    = "tcp_sendmsg",
+       },
+       .entry  = JPROBE_ENTRY(jtcp_sendmsg),
 };
 
 
index 6d6142f9c478baa8c85dcf1d174a5a88f66d783a..865d75214a9ab1d741f3d8351359e95a0d8394e7 100644 (file)
@@ -675,6 +675,8 @@ do_append_data:
                udp_flush_pending_frames(sk);
        else if (!corkreq)
                err = udp_push_pending_frames(sk, up);
+       else if (unlikely(skb_queue_empty(&sk->sk_write_queue)))
+               up->pending = 0;
        release_sock(sk);
 
 out:
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c
new file mode 100644 (file)
index 0000000..89cf59e
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * xfrm4_mode_beet.c - BEET mode encapsulation for IPv4.
+ *
+ * Copyright (c) 2006 Diego Beltrami <diego.beltrami@gmail.com>
+ *                    Miika Komu     <miika@iki.fi>
+ *                    Herbert Xu     <herbert@gondor.apana.org.au>
+ *                    Abhinav Pathak <abhinav.pathak@hiit.fi>
+ *                    Jeff Ahrenholz <ahrenholz@gmail.com>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/stringify.h>
+#include <net/dst.h>
+#include <net/ip.h>
+#include <net/xfrm.h>
+
+/* Add encapsulation header.
+ *
+ * The top IP header will be constructed per draft-nikander-esp-beet-mode-06.txt.
+ * The following fields in it shall be filled in by x->type->output:
+ *      tot_len
+ *      check
+ *
+ * On exit, skb->h will be set to the start of the payload to be processed
+ * by x->type->output and skb->nh will be set to the top IP header.
+ */
+static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
+{
+       struct iphdr *iph, *top_iph = NULL;
+       int hdrlen, optlen;
+
+       iph = skb->nh.iph;
+       skb->h.ipiph = iph;
+
+       hdrlen = 0;
+       optlen = iph->ihl * 4 - sizeof(*iph);
+       if (unlikely(optlen))
+               hdrlen += IPV4_BEET_PHMAXLEN - (optlen & 4);
+
+       skb->nh.raw = skb_push(skb, x->props.header_len + hdrlen);
+       top_iph = skb->nh.iph;
+       hdrlen = iph->ihl * 4 - optlen;
+       skb->h.raw += hdrlen;
+
+       memmove(top_iph, iph, hdrlen);
+       if (unlikely(optlen)) {
+               struct ip_beet_phdr *ph;
+
+               BUG_ON(optlen < 0);
+
+               ph = (struct ip_beet_phdr *)skb->h.raw;
+               ph->padlen = 4 - (optlen & 4);
+               ph->hdrlen = (optlen + ph->padlen + sizeof(*ph)) / 8;
+               ph->nexthdr = top_iph->protocol;
+
+               top_iph->protocol = IPPROTO_BEETPH;
+               top_iph->ihl = sizeof(struct iphdr) / 4;
+       }
+
+       top_iph->saddr = x->props.saddr.a4;
+       top_iph->daddr = x->id.daddr.a4;
+
+       return 0;
+}
+
+static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb)
+{
+       struct iphdr *iph = skb->nh.iph;
+       int phlen = 0;
+       int optlen = 0;
+       __u8 ph_nexthdr = 0, protocol = 0;
+       int err = -EINVAL;
+
+       protocol = iph->protocol;
+
+       if (unlikely(iph->protocol == IPPROTO_BEETPH)) {
+               struct ip_beet_phdr *ph = (struct ip_beet_phdr*)(iph + 1);
+
+               if (!pskb_may_pull(skb, sizeof(*ph)))
+                       goto out;
+
+               phlen = ph->hdrlen * 8;
+               optlen = phlen - ph->padlen - sizeof(*ph);
+               if (optlen < 0 || optlen & 3 || optlen > 250)
+                       goto out;
+
+               if (!pskb_may_pull(skb, phlen))
+                       goto out;
+
+               ph_nexthdr = ph->nexthdr;
+       }
+
+       skb_push(skb, sizeof(*iph) - phlen + optlen);
+       memmove(skb->data, skb->nh.raw, sizeof(*iph));
+       skb->nh.raw = skb->data;
+
+       iph = skb->nh.iph;
+       iph->ihl = (sizeof(*iph) + optlen) / 4;
+       iph->tot_len = htons(skb->len);
+       iph->daddr = x->sel.daddr.a4;
+       iph->saddr = x->sel.saddr.a4;
+       if (ph_nexthdr)
+               iph->protocol = ph_nexthdr;
+       else
+               iph->protocol = protocol;
+       iph->check = 0;
+       iph->check = ip_fast_csum(skb->nh.raw, iph->ihl);
+       err = 0;
+out:
+       return err;
+}
+
+static struct xfrm_mode xfrm4_beet_mode = {
+       .input = xfrm4_beet_input,
+       .output = xfrm4_beet_output,
+       .owner = THIS_MODULE,
+       .encap = XFRM_MODE_BEET,
+};
+
+static int __init xfrm4_beet_init(void)
+{
+       return xfrm_register_mode(&xfrm4_beet_mode, AF_INET);
+}
+
+static void __exit xfrm4_beet_exit(void)
+{
+       int err;
+
+       err = xfrm_unregister_mode(&xfrm4_beet_mode, AF_INET);
+       BUG_ON(err);
+}
+
+module_init(xfrm4_beet_init);
+module_exit(xfrm4_beet_exit);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_XFRM_MODE(AF_INET, XFRM_MODE_BEET);
index a2d211da2abac43dd8f9807372f0d0c096cd0099..a460e8132b4d471c0b282f47c58996ddd4f35315 100644 (file)
@@ -136,6 +136,16 @@ config INET6_XFRM_MODE_TUNNEL
 
          If unsure, say Y.
 
+config INET6_XFRM_MODE_BEET
+       tristate "IPv6: IPsec BEET mode"
+       depends on IPV6
+       default IPV6
+       select XFRM
+       ---help---
+         Support for IPsec BEET mode.
+
+         If unsure, say Y.
+
 config INET6_XFRM_MODE_ROUTEOPTIMIZATION
        tristate "IPv6: MIPv6 route optimization mode (EXPERIMENTAL)"
        depends on IPV6 && EXPERIMENTAL
index 0213c6612b58da9025cffdd2dfbe76e0115fc311..87274e47fe32736d7ec0261f44ef3d34ecd0ef64 100644 (file)
@@ -26,6 +26,7 @@ obj-$(CONFIG_INET6_TUNNEL) += tunnel6.o
 obj-$(CONFIG_INET6_XFRM_MODE_TRANSPORT) += xfrm6_mode_transport.o
 obj-$(CONFIG_INET6_XFRM_MODE_TUNNEL) += xfrm6_mode_tunnel.o
 obj-$(CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION) += xfrm6_mode_ro.o
+obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o
 obj-$(CONFIG_NETFILTER)        += netfilter/
 
 obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o
index a2860e35efd7d68ee67d3839e4b064aa6f3a574e..71f59f18ede820749317fe333c96221fee58ce5f 100644 (file)
@@ -199,6 +199,7 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x)
 {
        struct xfrm_state *t = NULL;
+       u8 mode = XFRM_MODE_TUNNEL;
 
        t = xfrm_state_alloc();
        if (!t)
@@ -212,7 +213,9 @@ static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x)
        memcpy(t->id.daddr.a6, x->id.daddr.a6, sizeof(struct in6_addr));
        memcpy(&t->sel, &x->sel, sizeof(t->sel));
        t->props.family = AF_INET6;
-       t->props.mode = XFRM_MODE_TUNNEL;
+       if (x->props.mode == XFRM_MODE_BEET)
+               mode = x->props.mode;
+       t->props.mode = mode;
        memcpy(t->props.saddr.a6, x->props.saddr.a6, sizeof(struct in6_addr));
 
        if (xfrm_init_state(t))
index 9662561701d1c8463b53f0f1fe73dd89a2ba44d7..e0c3934a7e4bd82b81135e0e48f097299b3a2510 100644 (file)
@@ -546,7 +546,7 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
        struct in6_addr *daddr, *final_p = NULL, final;
        struct ipv6_txoptions *opt = NULL;
        struct ip6_flowlabel *flowlabel = NULL;
-       struct flowi *fl = &inet->cork.fl;
+       struct flowi fl;
        struct dst_entry *dst;
        int addr_len = msg->msg_namelen;
        int ulen = len;
@@ -626,19 +626,19 @@ do_udp_sendmsg:
        }
        ulen += sizeof(struct udphdr);
 
-       memset(fl, 0, sizeof(*fl));
+       memset(&fl, 0, sizeof(fl));
 
        if (sin6) {
                if (sin6->sin6_port == 0)
                        return -EINVAL;
 
-               fl->fl_ip_dport = sin6->sin6_port;
+               fl.fl_ip_dport = sin6->sin6_port;
                daddr = &sin6->sin6_addr;
 
                if (np->sndflow) {
-                       fl->fl6_flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK;
-                       if (fl->fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
-                               flowlabel = fl6_sock_lookup(sk, fl->fl6_flowlabel);
+                       fl.fl6_flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK;
+                       if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
+                               flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
                                if (flowlabel == NULL)
                                        return -EINVAL;
                                daddr = &flowlabel->dst;
@@ -656,32 +656,32 @@ do_udp_sendmsg:
                if (addr_len >= sizeof(struct sockaddr_in6) &&
                    sin6->sin6_scope_id &&
                    ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL)
-                       fl->oif = sin6->sin6_scope_id;
+                       fl.oif = sin6->sin6_scope_id;
        } else {
                if (sk->sk_state != TCP_ESTABLISHED)
                        return -EDESTADDRREQ;
 
-               fl->fl_ip_dport = inet->dport;
+               fl.fl_ip_dport = inet->dport;
                daddr = &np->daddr;
-               fl->fl6_flowlabel = np->flow_label;
+               fl.fl6_flowlabel = np->flow_label;
                connected = 1;
        }
 
-       if (!fl->oif)
-               fl->oif = sk->sk_bound_dev_if;
+       if (!fl.oif)
+               fl.oif = sk->sk_bound_dev_if;
 
        if (msg->msg_controllen) {
                opt = &opt_space;
                memset(opt, 0, sizeof(struct ipv6_txoptions));
                opt->tot_len = sizeof(*opt);
 
-               err = datagram_send_ctl(msg, fl, opt, &hlimit, &tclass);
+               err = datagram_send_ctl(msg, &fl, opt, &hlimit, &tclass);
                if (err < 0) {
                        fl6_sock_release(flowlabel);
                        return err;
                }
-               if ((fl->fl6_flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) {
-                       flowlabel = fl6_sock_lookup(sk, fl->fl6_flowlabel);
+               if ((fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) {
+                       flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
                        if (flowlabel == NULL)
                                return -EINVAL;
                }
@@ -695,39 +695,39 @@ do_udp_sendmsg:
                opt = fl6_merge_options(&opt_space, flowlabel, opt);
        opt = ipv6_fixup_options(&opt_space, opt);
 
-       fl->proto = IPPROTO_UDP;
-       ipv6_addr_copy(&fl->fl6_dst, daddr);
-       if (ipv6_addr_any(&fl->fl6_src) && !ipv6_addr_any(&np->saddr))
-               ipv6_addr_copy(&fl->fl6_src, &np->saddr);
-       fl->fl_ip_sport = inet->sport;
+       fl.proto = IPPROTO_UDP;
+       ipv6_addr_copy(&fl.fl6_dst, daddr);
+       if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr))
+               ipv6_addr_copy(&fl.fl6_src, &np->saddr);
+       fl.fl_ip_sport = inet->sport;
        
        /* merge ip6_build_xmit from ip6_output */
        if (opt && opt->srcrt) {
                struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
-               ipv6_addr_copy(&final, &fl->fl6_dst);
-               ipv6_addr_copy(&fl->fl6_dst, rt0->addr);
+               ipv6_addr_copy(&final, &fl.fl6_dst);
+               ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
                final_p = &final;
                connected = 0;
        }
 
-       if (!fl->oif && ipv6_addr_is_multicast(&fl->fl6_dst)) {
-               fl->oif = np->mcast_oif;
+       if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) {
+               fl.oif = np->mcast_oif;
                connected = 0;
        }
 
-       security_sk_classify_flow(sk, fl);
+       security_sk_classify_flow(sk, &fl);
 
-       err = ip6_sk_dst_lookup(sk, &dst, fl);
+       err = ip6_sk_dst_lookup(sk, &dst, &fl);
        if (err)
                goto out;
        if (final_p)
-               ipv6_addr_copy(&fl->fl6_dst, final_p);
+               ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-       if ((err = xfrm_lookup(&dst, fl, sk, 0)) < 0)
+       if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
                goto out;
 
        if (hlimit < 0) {
-               if (ipv6_addr_is_multicast(&fl->fl6_dst))
+               if (ipv6_addr_is_multicast(&fl.fl6_dst))
                        hlimit = np->mcast_hops;
                else
                        hlimit = np->hop_limit;
@@ -763,21 +763,23 @@ back_from_confirm:
 do_append_data:
        up->len += ulen;
        err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, ulen,
-               sizeof(struct udphdr), hlimit, tclass, opt, fl,
+               sizeof(struct udphdr), hlimit, tclass, opt, &fl,
                (struct rt6_info*)dst,
                corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
        if (err)
                udp_v6_flush_pending_frames(sk);
        else if (!corkreq)
                err = udp_v6_push_pending_frames(sk, up);
+       else if (unlikely(skb_queue_empty(&sk->sk_write_queue)))
+               up->pending = 0;
 
        if (dst) {
                if (connected) {
                        ip6_dst_store(sk, dst,
-                                     ipv6_addr_equal(&fl->fl6_dst, &np->daddr) ?
+                                     ipv6_addr_equal(&fl.fl6_dst, &np->daddr) ?
                                      &np->daddr : NULL,
 #ifdef CONFIG_IPV6_SUBTREES
-                                     ipv6_addr_equal(&fl->fl6_src, &np->saddr) ?
+                                     ipv6_addr_equal(&fl.fl6_src, &np->saddr) ?
                                      &np->saddr :
 #endif
                                      NULL);
diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c
new file mode 100644 (file)
index 0000000..edcfffa
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * xfrm6_mode_beet.c - BEET mode encapsulation for IPv6.
+ *
+ * Copyright (c) 2006 Diego Beltrami <diego.beltrami@gmail.com>
+ *                    Miika Komu     <miika@iki.fi>
+ *                    Herbert Xu     <herbert@gondor.apana.org.au>
+ *                    Abhinav Pathak <abhinav.pathak@hiit.fi>
+ *                    Jeff Ahrenholz <ahrenholz@gmail.com>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/stringify.h>
+#include <net/dsfield.h>
+#include <net/dst.h>
+#include <net/inet_ecn.h>
+#include <net/ipv6.h>
+#include <net/xfrm.h>
+
+/* Add encapsulation header.
+ *
+ * The top IP header will be constructed per draft-nikander-esp-beet-mode-06.txt.
+ * The following fields in it shall be filled in by x->type->output:
+ *     payload_len
+ *
+ * On exit, skb->h will be set to the start of the encapsulation header to be
+ * filled in by x->type->output and skb->nh will be set to the nextheader field
+ * of the extension header directly preceding the encapsulation header, or in
+ * its absence, that of the top IP header.  The value of skb->data will always
+ * point to the top IP header.
+ */
+static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb)
+{
+       struct ipv6hdr *iph, *top_iph;
+       u8 *prevhdr;
+       int hdr_len;
+
+       skb_push(skb, x->props.header_len);
+       iph = skb->nh.ipv6h;
+
+       hdr_len = ip6_find_1stfragopt(skb, &prevhdr);
+       skb->nh.raw = prevhdr - x->props.header_len;
+       skb->h.raw = skb->data + hdr_len;
+       memmove(skb->data, iph, hdr_len);
+
+       skb->nh.raw = skb->data;
+       top_iph = skb->nh.ipv6h;
+       skb->nh.raw = &top_iph->nexthdr;
+       skb->h.ipv6h = top_iph + 1;
+
+       ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
+       ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
+
+       return 0;
+}
+
+static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb)
+{
+       struct ipv6hdr *ip6h;
+       int size = sizeof(struct ipv6hdr);
+       int err = -EINVAL;
+
+       if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
+               goto out;
+
+       skb_push(skb, size);
+       memmove(skb->data, skb->nh.raw, size);
+       skb->nh.raw = skb->data;
+
+       skb->mac.raw = memmove(skb->data - skb->mac_len,
+                              skb->mac.raw, skb->mac_len);
+
+       ip6h = skb->nh.ipv6h;
+       ip6h->payload_len = htons(skb->len - size);
+       ipv6_addr_copy(&ip6h->daddr, (struct in6_addr *) &x->sel.daddr.a6);
+       ipv6_addr_copy(&ip6h->saddr, (struct in6_addr *) &x->sel.saddr.a6);
+       err = 0;
+out:
+       return err;
+}
+
+static struct xfrm_mode xfrm6_beet_mode = {
+       .input = xfrm6_beet_input,
+       .output = xfrm6_beet_output,
+       .owner = THIS_MODULE,
+       .encap = XFRM_MODE_BEET,
+};
+
+static int __init xfrm6_beet_init(void)
+{
+       return xfrm_register_mode(&xfrm6_beet_mode, AF_INET6);
+}
+
+static void __exit xfrm6_beet_exit(void)
+{
+       int err;
+
+       err = xfrm_unregister_mode(&xfrm6_beet_mode, AF_INET6);
+       BUG_ON(err);
+}
+
+module_init(xfrm6_beet_init);
+module_exit(xfrm6_beet_exit);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_XFRM_MODE(AF_INET6, XFRM_MODE_BEET);
index 3bcdb467efc5658dd525d924acfd3faffd2adccb..d50a02030ad72dbf1598a87d24812203241a36a4 100644 (file)
@@ -79,7 +79,7 @@ static struct tty_driver *driver;
 
 hashbin_t *ircomm_tty = NULL;
 
-static struct tty_operations ops = {
+static const struct tty_operations ops = {
        .open            = ircomm_tty_open,
        .close           = ircomm_tty_close,
        .write           = ircomm_tty_write,
index 0a28d2c5c44fcf5672e71dc4f72395c288cf4d11..ce94732b8e231d68c7cda461f5168103cf8b45f8 100644 (file)
@@ -365,7 +365,7 @@ config NETFILTER_XT_MATCH_MULTIPORT
 
 config NETFILTER_XT_MATCH_PHYSDEV
        tristate '"physdev" match support'
-       depends on NETFILTER_XTABLES && BRIDGE_NETFILTER
+       depends on NETFILTER_XTABLES && BRIDGE && BRIDGE_NETFILTER
        help
          Physdev packet matching matches against the physical bridge ports
          the IP packet arrived on or will leave by.
diff --git a/net/sched/estimator.c b/net/sched/estimator.c
deleted file mode 100644 (file)
index 0ebc98e..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * net/sched/estimator.c       Simple rate estimator.
- *
- *             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.
- *
- * Authors:    Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
- */
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/jiffies.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <linux/rtnetlink.h>
-#include <linux/init.h>
-#include <net/sock.h>
-#include <net/pkt_sched.h>
-
-/*
-   This code is NOT intended to be used for statistics collection,
-   its purpose is to provide a base for statistical multiplexing
-   for controlled load service.
-   If you need only statistics, run a user level daemon which
-   periodically reads byte counters.
-
-   Unfortunately, rate estimation is not a very easy task.
-   F.e. I did not find a simple way to estimate the current peak rate
-   and even failed to formulate the problem 8)8)
-
-   So I preferred not to built an estimator into the scheduler,
-   but run this task separately.
-   Ideally, it should be kernel thread(s), but for now it runs
-   from timers, which puts apparent top bounds on the number of rated
-   flows, has minimal overhead on small, but is enough
-   to handle controlled load service, sets of aggregates.
-
-   We measure rate over A=(1<<interval) seconds and evaluate EWMA:
-
-   avrate = avrate*(1-W) + rate*W
-
-   where W is chosen as negative power of 2: W = 2^(-ewma_log)
-
-   The resulting time constant is:
-
-   T = A/(-ln(1-W))
-
-
-   NOTES.
-
-   * The stored value for avbps is scaled by 2^5, so that maximal
-     rate is ~1Gbit, avpps is scaled by 2^10.
-
-   * Minimal interval is HZ/4=250msec (it is the greatest common divisor
-     for HZ=100 and HZ=1024 8)), maximal interval
-     is (HZ*2^EST_MAX_INTERVAL)/4 = 8sec. Shorter intervals
-     are too expensive, longer ones can be implemented
-     at user level painlessly.
- */
-
-#define EST_MAX_INTERVAL       5
-
-struct qdisc_estimator
-{
-       struct qdisc_estimator  *next;
-       struct tc_stats         *stats;
-       spinlock_t              *stats_lock;
-       unsigned                interval;
-       int                     ewma_log;
-       u64                     last_bytes;
-       u32                     last_packets;
-       u32                     avpps;
-       u32                     avbps;
-};
-
-struct qdisc_estimator_head
-{
-       struct timer_list       timer;
-       struct qdisc_estimator  *list;
-};
-
-static struct qdisc_estimator_head elist[EST_MAX_INTERVAL+1];
-
-/* Estimator array lock */
-static DEFINE_RWLOCK(est_lock);
-
-static void est_timer(unsigned long arg)
-{
-       int idx = (int)arg;
-       struct qdisc_estimator *e;
-
-       read_lock(&est_lock);
-       for (e = elist[idx].list; e; e = e->next) {
-               struct tc_stats *st = e->stats;
-               u64 nbytes;
-               u32 npackets;
-               u32 rate;
-
-               spin_lock(e->stats_lock);
-               nbytes = st->bytes;
-               npackets = st->packets;
-               rate = (nbytes - e->last_bytes)<<(7 - idx);
-               e->last_bytes = nbytes;
-               e->avbps += ((long)rate - (long)e->avbps) >> e->ewma_log;
-               st->bps = (e->avbps+0xF)>>5;
-
-               rate = (npackets - e->last_packets)<<(12 - idx);
-               e->last_packets = npackets;
-               e->avpps += ((long)rate - (long)e->avpps) >> e->ewma_log;
-               e->stats->pps = (e->avpps+0x1FF)>>10;
-               spin_unlock(e->stats_lock);
-       }
-
-       mod_timer(&elist[idx].timer, jiffies + ((HZ<<idx)/4));
-       read_unlock(&est_lock);
-}
-
-int qdisc_new_estimator(struct tc_stats *stats, spinlock_t *stats_lock, struct rtattr *opt)
-{
-       struct qdisc_estimator *est;
-       struct tc_estimator *parm = RTA_DATA(opt);
-
-       if (RTA_PAYLOAD(opt) < sizeof(*parm))
-               return -EINVAL;
-
-       if (parm->interval < -2 || parm->interval > 3)
-               return -EINVAL;
-
-       est = kzalloc(sizeof(*est), GFP_KERNEL);
-       if (est == NULL)
-               return -ENOBUFS;
-
-       est->interval = parm->interval + 2;
-       est->stats = stats;
-       est->stats_lock = stats_lock;
-       est->ewma_log = parm->ewma_log;
-       est->last_bytes = stats->bytes;
-       est->avbps = stats->bps<<5;
-       est->last_packets = stats->packets;
-       est->avpps = stats->pps<<10;
-
-       est->next = elist[est->interval].list;
-       if (est->next == NULL) {
-               init_timer(&elist[est->interval].timer);
-               elist[est->interval].timer.data = est->interval;
-               elist[est->interval].timer.expires = jiffies + ((HZ<<est->interval)/4);
-               elist[est->interval].timer.function = est_timer;
-               add_timer(&elist[est->interval].timer);
-       }
-       write_lock_bh(&est_lock);
-       elist[est->interval].list = est;
-       write_unlock_bh(&est_lock);
-       return 0;
-}
-
-void qdisc_kill_estimator(struct tc_stats *stats)
-{
-       int idx;
-       struct qdisc_estimator *est, **pest;
-
-       for (idx=0; idx <= EST_MAX_INTERVAL; idx++) {
-               int killed = 0;
-               pest = &elist[idx].list;
-               while ((est=*pest) != NULL) {
-                       if (est->stats != stats) {
-                               pest = &est->next;
-                               continue;
-                       }
-
-                       write_lock_bh(&est_lock);
-                       *pest = est->next;
-                       write_unlock_bh(&est_lock);
-
-                       kfree(est);
-                       killed++;
-               }
-               if (killed && elist[idx].list == NULL)
-                       del_timer(&elist[idx].timer);
-       }
-}
-
-EXPORT_SYMBOL(qdisc_kill_estimator);
-EXPORT_SYMBOL(qdisc_new_estimator);
index 6c058e3660c0c28ec9e6d85cd79f92c94c391539..bb3ddd4784b1cebfd4668dc15df844b484b36267 100644 (file)
@@ -391,7 +391,7 @@ static inline void htb_add_class_to_row(struct htb_sched *q,
 /* If this triggers, it is a bug in this code, but it need not be fatal */
 static void htb_safe_rb_erase(struct rb_node *rb, struct rb_root *root)
 {
-       if (!RB_EMPTY_NODE(rb)) {
+       if (RB_EMPTY_NODE(rb)) {
                WARN_ON(1);
        } else {
                rb_erase(rb, root);
index 01918f7a301aaa11f8b2375e6173dc52dee84645..6c9b9b326d764991f4687b9a2799f6c245448834 100644 (file)
@@ -825,7 +825,7 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
                        break;
                case FIOGETOWN:
                case SIOCGPGRP:
-                       err = put_user(sock->file->f_owner.pid,
+                       err = put_user(f_getown(sock->file),
                                       (int __user *)argp);
                        break;
                case SIOCGIFBR:
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 124ff0ceb55b2ee20ce47d6f3358a966de37ddb5..78696f2dc7d6d402ef200f140f897388ce383db1 100644 (file)
@@ -161,10 +161,10 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
        }
 
        /* save the nodename */
-       clnt->cl_nodelen = strlen(system_utsname.nodename);
+       clnt->cl_nodelen = strlen(utsname()->nodename);
        if (clnt->cl_nodelen > UNX_MAXNODENAME)
                clnt->cl_nodelen = UNX_MAXNODENAME;
-       memcpy(clnt->cl_nodename, system_utsname.nodename, clnt->cl_nodelen);
+       memcpy(clnt->cl_nodename, utsname()->nodename, clnt->cl_nodelen);
        return clnt;
 
 out_no_auth:
index 26c0531d7e253739d5e0a7b9f38225ac0e311da6..192dff5dabcbc76258a378179d7132f5e3845bf8 100644 (file)
@@ -70,6 +70,8 @@ EXPORT_SYMBOL(put_rpccred);
 /* RPC server stuff */
 EXPORT_SYMBOL(svc_create);
 EXPORT_SYMBOL(svc_create_thread);
+EXPORT_SYMBOL(svc_create_pooled);
+EXPORT_SYMBOL(svc_set_num_threads);
 EXPORT_SYMBOL(svc_exit_thread);
 EXPORT_SYMBOL(svc_destroy);
 EXPORT_SYMBOL(svc_drop);
index 44b8d9d4c18a7d09e5929688e45eab41cdc60ef8..c2c8bb20d07f7171aad6a74e9c4cf323fd4f03ca 100644 (file)
@@ -4,6 +4,10 @@
  * High-level RPC service routines
  *
  * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
+ *
+ * Multiple threads pools and NUMAisation
+ * Copyright (c) 2006 Silicon Graphics, Inc.
+ * by Greg Banks <gnb@melbourne.sgi.com>
  */
 
 #include <linux/linkage.h>
@@ -12,6 +16,8 @@
 #include <linux/net.h>
 #include <linux/in.h>
 #include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
 
 #include <linux/sunrpc/types.h>
 #include <linux/sunrpc/xdr.h>
 #define RPCDBG_FACILITY        RPCDBG_SVCDSP
 #define RPC_PARANOIA 1
 
+/*
+ * Mode for mapping cpus to pools.
+ */
+enum {
+       SVC_POOL_NONE = -1,     /* uninitialised, choose one of the others */
+       SVC_POOL_GLOBAL,        /* no mapping, just a single global pool
+                                * (legacy & UP mode) */
+       SVC_POOL_PERCPU,        /* one pool per cpu */
+       SVC_POOL_PERNODE        /* one pool per numa node */
+};
+
+/*
+ * Structure for mapping cpus to pools and vice versa.
+ * Setup once during sunrpc initialisation.
+ */
+static struct svc_pool_map {
+       int mode;                       /* Note: int not enum to avoid
+                                        * warnings about "enumeration value
+                                        * not handled in switch" */
+       unsigned int npools;
+       unsigned int *pool_to;          /* maps pool id to cpu or node */
+       unsigned int *to_pool;          /* maps cpu or node to pool id */
+} svc_pool_map = {
+       .mode = SVC_POOL_NONE
+};
+
+
+/*
+ * Detect best pool mapping mode heuristically,
+ * according to the machine's topology.
+ */
+static int
+svc_pool_map_choose_mode(void)
+{
+       unsigned int node;
+
+       if (num_online_nodes() > 1) {
+               /*
+                * Actually have multiple NUMA nodes,
+                * so split pools on NUMA node boundaries
+                */
+               return SVC_POOL_PERNODE;
+       }
+
+       node = any_online_node(node_online_map);
+       if (nr_cpus_node(node) > 2) {
+               /*
+                * Non-trivial SMP, or CONFIG_NUMA on
+                * non-NUMA hardware, e.g. with a generic
+                * x86_64 kernel on Xeons.  In this case we
+                * want to divide the pools on cpu boundaries.
+                */
+               return SVC_POOL_PERCPU;
+       }
+
+       /* default: one global pool */
+       return SVC_POOL_GLOBAL;
+}
+
+/*
+ * Allocate the to_pool[] and pool_to[] arrays.
+ * Returns 0 on success or an errno.
+ */
+static int
+svc_pool_map_alloc_arrays(struct svc_pool_map *m, unsigned int maxpools)
+{
+       m->to_pool = kcalloc(maxpools, sizeof(unsigned int), GFP_KERNEL);
+       if (!m->to_pool)
+               goto fail;
+       m->pool_to = kcalloc(maxpools, sizeof(unsigned int), GFP_KERNEL);
+       if (!m->pool_to)
+               goto fail_free;
+
+       return 0;
+
+fail_free:
+       kfree(m->to_pool);
+fail:
+       return -ENOMEM;
+}
+
+/*
+ * Initialise the pool map for SVC_POOL_PERCPU mode.
+ * Returns number of pools or <0 on error.
+ */
+static int
+svc_pool_map_init_percpu(struct svc_pool_map *m)
+{
+       unsigned int maxpools = highest_possible_processor_id()+1;
+       unsigned int pidx = 0;
+       unsigned int cpu;
+       int err;
+
+       err = svc_pool_map_alloc_arrays(m, maxpools);
+       if (err)
+               return err;
+
+       for_each_online_cpu(cpu) {
+               BUG_ON(pidx > maxpools);
+               m->to_pool[cpu] = pidx;
+               m->pool_to[pidx] = cpu;
+               pidx++;
+       }
+       /* cpus brought online later all get mapped to pool0, sorry */
+
+       return pidx;
+};
+
+
+/*
+ * Initialise the pool map for SVC_POOL_PERNODE mode.
+ * Returns number of pools or <0 on error.
+ */
+static int
+svc_pool_map_init_pernode(struct svc_pool_map *m)
+{
+       unsigned int maxpools = highest_possible_node_id()+1;
+       unsigned int pidx = 0;
+       unsigned int node;
+       int err;
+
+       err = svc_pool_map_alloc_arrays(m, maxpools);
+       if (err)
+               return err;
+
+       for_each_node_with_cpus(node) {
+               /* some architectures (e.g. SN2) have cpuless nodes */
+               BUG_ON(pidx > maxpools);
+               m->to_pool[node] = pidx;
+               m->pool_to[pidx] = node;
+               pidx++;
+       }
+       /* nodes brought online later all get mapped to pool0, sorry */
+
+       return pidx;
+}
+
+
+/*
+ * Build the global map of cpus to pools and vice versa.
+ */
+static unsigned int
+svc_pool_map_init(void)
+{
+       struct svc_pool_map *m = &svc_pool_map;
+       int npools = -1;
+
+       if (m->mode != SVC_POOL_NONE)
+               return m->npools;
+
+       m->mode = svc_pool_map_choose_mode();
+
+       switch (m->mode) {
+       case SVC_POOL_PERCPU:
+               npools = svc_pool_map_init_percpu(m);
+               break;
+       case SVC_POOL_PERNODE:
+               npools = svc_pool_map_init_pernode(m);
+               break;
+       }
+
+       if (npools < 0) {
+               /* default, or memory allocation failure */
+               npools = 1;
+               m->mode = SVC_POOL_GLOBAL;
+       }
+       m->npools = npools;
+
+       return m->npools;
+}
+
+/*
+ * Set the current thread's cpus_allowed mask so that it
+ * will only run on cpus in the given pool.
+ *
+ * Returns 1 and fills in oldmask iff a cpumask was applied.
+ */
+static inline int
+svc_pool_map_set_cpumask(unsigned int pidx, cpumask_t *oldmask)
+{
+       struct svc_pool_map *m = &svc_pool_map;
+       unsigned int node; /* or cpu */
+
+       /*
+        * The caller checks for sv_nrpools > 1, which
+        * implies that we've been initialized and the
+        * map mode is not NONE.
+        */
+       BUG_ON(m->mode == SVC_POOL_NONE);
+
+       switch (m->mode)
+       {
+       default:
+               return 0;
+       case SVC_POOL_PERCPU:
+               node = m->pool_to[pidx];
+               *oldmask = current->cpus_allowed;
+               set_cpus_allowed(current, cpumask_of_cpu(node));
+               return 1;
+       case SVC_POOL_PERNODE:
+               node = m->pool_to[pidx];
+               *oldmask = current->cpus_allowed;
+               set_cpus_allowed(current, node_to_cpumask(node));
+               return 1;
+       }
+}
+
+/*
+ * Use the mapping mode to choose a pool for a given CPU.
+ * Used when enqueueing an incoming RPC.  Always returns
+ * a non-NULL pool pointer.
+ */
+struct svc_pool *
+svc_pool_for_cpu(struct svc_serv *serv, int cpu)
+{
+       struct svc_pool_map *m = &svc_pool_map;
+       unsigned int pidx = 0;
+
+       /*
+        * SVC_POOL_NONE happens in a pure client when
+        * lockd is brought up, so silently treat it the
+        * same as SVC_POOL_GLOBAL.
+        */
+
+       switch (m->mode) {
+       case SVC_POOL_PERCPU:
+               pidx = m->to_pool[cpu];
+               break;
+       case SVC_POOL_PERNODE:
+               pidx = m->to_pool[cpu_to_node(cpu)];
+               break;
+       }
+       return &serv->sv_pools[pidx % serv->sv_nrpools];
+}
+
+
 /*
  * Create an RPC service
  */
-struct svc_serv *
-svc_create(struct svc_program *prog, unsigned int bufsize)
+static struct svc_serv *
+__svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
+          void (*shutdown)(struct svc_serv *serv))
 {
        struct svc_serv *serv;
        int vers;
        unsigned int xdrsize;
+       unsigned int i;
 
        if (!(serv = kzalloc(sizeof(*serv), GFP_KERNEL)))
                return NULL;
@@ -39,6 +283,7 @@ svc_create(struct svc_program *prog, unsigned int bufsize)
        serv->sv_nrthreads = 1;
        serv->sv_stats     = prog->pg_stats;
        serv->sv_bufsz     = bufsize? bufsize : 4096;
+       serv->sv_shutdown  = shutdown;
        xdrsize = 0;
        while (prog) {
                prog->pg_lovers = prog->pg_nvers-1;
@@ -53,20 +298,68 @@ svc_create(struct svc_program *prog, unsigned int bufsize)
                prog = prog->pg_next;
        }
        serv->sv_xdrsize   = xdrsize;
-       INIT_LIST_HEAD(&serv->sv_threads);
-       INIT_LIST_HEAD(&serv->sv_sockets);
        INIT_LIST_HEAD(&serv->sv_tempsocks);
        INIT_LIST_HEAD(&serv->sv_permsocks);
+       init_timer(&serv->sv_temptimer);
        spin_lock_init(&serv->sv_lock);
 
+       serv->sv_nrpools = npools;
+       serv->sv_pools =
+               kcalloc(sizeof(struct svc_pool), serv->sv_nrpools,
+                       GFP_KERNEL);
+       if (!serv->sv_pools) {
+               kfree(serv);
+               return NULL;
+       }
+
+       for (i = 0; i < serv->sv_nrpools; i++) {
+               struct svc_pool *pool = &serv->sv_pools[i];
+
+               dprintk("initialising pool %u for %s\n",
+                               i, serv->sv_name);
+
+               pool->sp_id = i;
+               INIT_LIST_HEAD(&pool->sp_threads);
+               INIT_LIST_HEAD(&pool->sp_sockets);
+               INIT_LIST_HEAD(&pool->sp_all_threads);
+               spin_lock_init(&pool->sp_lock);
+       }
+
+
        /* Remove any stale portmap registrations */
        svc_register(serv, 0, 0);
 
        return serv;
 }
 
+struct svc_serv *
+svc_create(struct svc_program *prog, unsigned int bufsize,
+               void (*shutdown)(struct svc_serv *serv))
+{
+       return __svc_create(prog, bufsize, /*npools*/1, shutdown);
+}
+
+struct svc_serv *
+svc_create_pooled(struct svc_program *prog, unsigned int bufsize,
+               void (*shutdown)(struct svc_serv *serv),
+                 svc_thread_fn func, int sig, struct module *mod)
+{
+       struct svc_serv *serv;
+       unsigned int npools = svc_pool_map_init();
+
+       serv = __svc_create(prog, bufsize, npools, shutdown);
+
+       if (serv != NULL) {
+               serv->sv_function = func;
+               serv->sv_kill_signal = sig;
+               serv->sv_module = mod;
+       }
+
+       return serv;
+}
+
 /*
- * Destroy an RPC service
+ * Destroy an RPC service.  Should be called with the BKL held
  */
 void
 svc_destroy(struct svc_serv *serv)
@@ -85,12 +378,17 @@ svc_destroy(struct svc_serv *serv)
        } else
                printk("svc_destroy: no threads for serv=%p!\n", serv);
 
+       del_timer_sync(&serv->sv_temptimer);
+
        while (!list_empty(&serv->sv_tempsocks)) {
                svsk = list_entry(serv->sv_tempsocks.next,
                                  struct svc_sock,
                                  sk_list);
                svc_delete_socket(svsk);
        }
+       if (serv->sv_shutdown)
+               serv->sv_shutdown(serv);
+
        while (!list_empty(&serv->sv_permsocks)) {
                svsk = list_entry(serv->sv_permsocks.next,
                                  struct svc_sock,
@@ -102,6 +400,7 @@ svc_destroy(struct svc_serv *serv)
 
        /* Unregister service with the portmapper */
        svc_register(serv, 0, 0);
+       kfree(serv->sv_pools);
        kfree(serv);
 }
 
@@ -118,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;
 }
 
@@ -139,24 +435,25 @@ 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]);
 }
 
 /*
- * Create a server thread
+ * Create a thread in the given pool.  Caller must hold BKL.
+ * On a NUMA or SMP machine, with a multi-pool serv, the thread
+ * will be restricted to run on the cpus belonging to the pool.
  */
-int
-svc_create_thread(svc_thread_fn func, struct svc_serv *serv)
+static int
+__svc_create_thread(svc_thread_fn func, struct svc_serv *serv,
+                   struct svc_pool *pool)
 {
        struct svc_rqst *rqstp;
        int             error = -ENOMEM;
+       int             have_oldmask = 0;
+       cpumask_t       oldmask;
 
        rqstp = kzalloc(sizeof(*rqstp), GFP_KERNEL);
        if (!rqstp)
@@ -170,8 +467,21 @@ svc_create_thread(svc_thread_fn func, struct svc_serv *serv)
                goto out_thread;
 
        serv->sv_nrthreads++;
+       spin_lock_bh(&pool->sp_lock);
+       pool->sp_nrthreads++;
+       list_add(&rqstp->rq_all, &pool->sp_all_threads);
+       spin_unlock_bh(&pool->sp_lock);
        rqstp->rq_server = serv;
+       rqstp->rq_pool = pool;
+
+       if (serv->sv_nrpools > 1)
+               have_oldmask = svc_pool_map_set_cpumask(pool->sp_id, &oldmask);
+
        error = kernel_thread((int (*)(void *)) func, rqstp, 0);
+
+       if (have_oldmask)
+               set_cpus_allowed(current, oldmask);
+
        if (error < 0)
                goto out_thread;
        svc_sock_update_bufs(serv);
@@ -185,17 +495,136 @@ out_thread:
 }
 
 /*
- * Destroy an RPC server thread
+ * Create a thread in the default pool.  Caller must hold BKL.
+ */
+int
+svc_create_thread(svc_thread_fn func, struct svc_serv *serv)
+{
+       return __svc_create_thread(func, serv, &serv->sv_pools[0]);
+}
+
+/*
+ * Choose a pool in which to create a new thread, for svc_set_num_threads
+ */
+static inline struct svc_pool *
+choose_pool(struct svc_serv *serv, struct svc_pool *pool, unsigned int *state)
+{
+       if (pool != NULL)
+               return pool;
+
+       return &serv->sv_pools[(*state)++ % serv->sv_nrpools];
+}
+
+/*
+ * Choose a thread to kill, for svc_set_num_threads
+ */
+static inline struct task_struct *
+choose_victim(struct svc_serv *serv, struct svc_pool *pool, unsigned int *state)
+{
+       unsigned int i;
+       struct task_struct *task = NULL;
+
+       if (pool != NULL) {
+               spin_lock_bh(&pool->sp_lock);
+       } else {
+               /* choose a pool in round-robin fashion */
+               for (i = 0; i < serv->sv_nrpools; i++) {
+                       pool = &serv->sv_pools[--(*state) % serv->sv_nrpools];
+                       spin_lock_bh(&pool->sp_lock);
+                       if (!list_empty(&pool->sp_all_threads))
+                               goto found_pool;
+                       spin_unlock_bh(&pool->sp_lock);
+               }
+               return NULL;
+       }
+
+found_pool:
+       if (!list_empty(&pool->sp_all_threads)) {
+               struct svc_rqst *rqstp;
+
+               /*
+                * Remove from the pool->sp_all_threads list
+                * so we don't try to kill it again.
+                */
+               rqstp = list_entry(pool->sp_all_threads.next, struct svc_rqst, rq_all);
+               list_del_init(&rqstp->rq_all);
+               task = rqstp->rq_task;
+       }
+       spin_unlock_bh(&pool->sp_lock);
+
+       return task;
+}
+
+/*
+ * Create or destroy enough new threads to make the number
+ * of threads the given number.  If `pool' is non-NULL, applies
+ * only to threads in that pool, otherwise round-robins between
+ * all pools.  Must be called with a svc_get() reference and
+ * the BKL held.
+ *
+ * Destroying threads relies on the service threads filling in
+ * rqstp->rq_task, which only the nfs ones do.  Assumes the serv
+ * has been created using svc_create_pooled().
+ *
+ * Based on code that used to be in nfsd_svc() but tweaked
+ * to be pool-aware.
+ */
+int
+svc_set_num_threads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
+{
+       struct task_struct *victim;
+       int error = 0;
+       unsigned int state = serv->sv_nrthreads-1;
+
+       if (pool == NULL) {
+               /* The -1 assumes caller has done a svc_get() */
+               nrservs -= (serv->sv_nrthreads-1);
+       } else {
+               spin_lock_bh(&pool->sp_lock);
+               nrservs -= pool->sp_nrthreads;
+               spin_unlock_bh(&pool->sp_lock);
+       }
+
+       /* create new threads */
+       while (nrservs > 0) {
+               nrservs--;
+               __module_get(serv->sv_module);
+               error = __svc_create_thread(serv->sv_function, serv,
+                                           choose_pool(serv, pool, &state));
+               if (error < 0) {
+                       module_put(serv->sv_module);
+                       break;
+               }
+       }
+       /* destroy old threads */
+       while (nrservs < 0 &&
+              (victim = choose_victim(serv, pool, &state)) != NULL) {
+               send_sig(serv->sv_kill_signal, victim, 1);
+               nrservs++;
+       }
+
+       return error;
+}
+
+/*
+ * Called from a server thread as it's exiting.  Caller must hold BKL.
  */
 void
 svc_exit_thread(struct svc_rqst *rqstp)
 {
        struct svc_serv *serv = rqstp->rq_server;
+       struct svc_pool *pool = rqstp->rq_pool;
 
        svc_release_buffer(rqstp);
        kfree(rqstp->rq_resp);
        kfree(rqstp->rq_argp);
        kfree(rqstp->rq_auth_data);
+
+       spin_lock_bh(&pool->sp_lock);
+       pool->sp_nrthreads--;
+       list_del(&rqstp->rq_all);
+       spin_unlock_bh(&pool->sp_lock);
+
        kfree(rqstp);
 
        /* Release the server */
@@ -215,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;
+                       }
                }
        }
 
@@ -248,19 +686,20 @@ svc_register(struct svc_serv *serv, int proto, unsigned short port)
  * Process the RPC request.
  */
 int
-svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
+svc_process(struct svc_rqst *rqstp)
 {
        struct svc_program      *progp;
        struct svc_version      *versp = NULL;  /* compiler food */
        struct svc_procedure    *procp = NULL;
        struct kvec *           argv = &rqstp->rq_arg.head[0];
        struct kvec *           resv = &rqstp->rq_res.head[0];
+       struct svc_serv         *serv = rqstp->rq_server;
        kxdrproc_t              xdr;
        __be32                  *statp;
        u32                     dir, prog, vers, proc;
        __be32                  auth_stat, rpc_stat;
        int                     auth_res;
-       __be32                  *accept_statp;
+       __be32                  *reply_statp;
 
        rpc_stat = rpc_success;
 
@@ -270,10 +709,10 @@ svc_process(struct svc_serv *serv, 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;
@@ -301,7 +740,7 @@ svc_process(struct svc_serv *serv, 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 */
 
@@ -449,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 */
@@ -489,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 1020d54b01d074a7fd8c1d25976a7d9fe800935c..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
 
@@ -348,12 +349,9 @@ int auth_unix_forget_old(struct auth_domain *dom)
 
 struct auth_domain *auth_unix_lookup(struct in_addr addr)
 {
-       struct ip_map key, *ipm;
+       struct ip_map *ipm;
        struct auth_domain *rv;
 
-       strcpy(key.m_class, "nfsd");
-       key.m_addr = addr;
-
        ipm = ip_map_lookup("nfsd", addr);
 
        if (!ipm)
@@ -378,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)
 {
@@ -387,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;
@@ -403,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 5b0fe1b66a23d5fbed578179268bedc15eae52c2..b39e7e2b648f67020a7706314cf142e81f017793 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
+#include <linux/file.h>
 #include <net/sock.h>
 #include <net/checksum.h>
 #include <net/ip.h>
 
 /* SMP locking strategy:
  *
- *     svc_serv->sv_lock protects most stuff for that service.
+ *     svc_pool->sp_lock protects most of the fields of that pool.
+ *     svc_serv->sv_lock protects sv_tempsocks, sv_permsocks, sv_tmpcnt.
+ *     when both need to be taken (rare), svc_serv->sv_lock is first.
+ *     BKL protects svc_serv->sv_nrthread.
+ *     svc_sock->sk_defer_lock protects the svc_sock->sk_deferred list
+ *     svc_sock->sk_flags.SK_BUSY prevents a svc_sock being enqueued multiply.
  *
  *     Some flags can be set to certain values at any time
  *     providing that certain rules are followed:
  *
- *     SK_BUSY  can be set to 0 at any time.  
- *             svc_sock_enqueue must be called afterwards
  *     SK_CONN, SK_DATA, can be set or cleared at any time.
  *             after a set, svc_sock_enqueue must be called.   
  *             after a clear, the socket must be read/accepted
@@ -73,23 +77,30 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_sock *svsk);
 static int svc_deferred_recv(struct svc_rqst *rqstp);
 static struct cache_deferred_req *svc_defer(struct cache_req *req);
 
+/* apparently the "standard" is that clients close
+ * idle connections after 5 minutes, servers after
+ * 6 minutes
+ *   http://www.connectathon.org/talks96/nfstcp.pdf
+ */
+static int svc_conn_age_period = 6*60;
+
 /*
- * Queue up an idle server thread.  Must have serv->sv_lock held.
+ * Queue up an idle server thread.  Must have pool->sp_lock held.
  * Note: this is really a stack rather than a queue, so that we only
- * use as many different threads as we need, and the rest don't polute
+ * use as many different threads as we need, and the rest don't pollute
  * the cache.
  */
 static inline void
-svc_serv_enqueue(struct svc_serv *serv, struct svc_rqst *rqstp)
+svc_thread_enqueue(struct svc_pool *pool, struct svc_rqst *rqstp)
 {
-       list_add(&rqstp->rq_list, &serv->sv_threads);
+       list_add(&rqstp->rq_list, &pool->sp_threads);
 }
 
 /*
- * Dequeue an nfsd thread.  Must have serv->sv_lock held.
+ * Dequeue an nfsd thread.  Must have pool->sp_lock held.
  */
 static inline void
-svc_serv_dequeue(struct svc_serv *serv, struct svc_rqst *rqstp)
+svc_thread_dequeue(struct svc_pool *pool, struct svc_rqst *rqstp)
 {
        list_del(&rqstp->rq_list);
 }
@@ -140,7 +151,9 @@ static void
 svc_sock_enqueue(struct svc_sock *svsk)
 {
        struct svc_serv *serv = svsk->sk_server;
+       struct svc_pool *pool;
        struct svc_rqst *rqstp;
+       int cpu;
 
        if (!(svsk->sk_flags &
              ( (1<<SK_CONN)|(1<<SK_DATA)|(1<<SK_CLOSE)|(1<<SK_DEFERRED)) ))
@@ -148,10 +161,14 @@ svc_sock_enqueue(struct svc_sock *svsk)
        if (test_bit(SK_DEAD, &svsk->sk_flags))
                return;
 
-       spin_lock_bh(&serv->sv_lock);
+       cpu = get_cpu();
+       pool = svc_pool_for_cpu(svsk->sk_server, cpu);
+       put_cpu();
+
+       spin_lock_bh(&pool->sp_lock);
 
-       if (!list_empty(&serv->sv_threads) && 
-           !list_empty(&serv->sv_sockets))
+       if (!list_empty(&pool->sp_threads) &&
+           !list_empty(&pool->sp_sockets))
                printk(KERN_ERR
                        "svc_sock_enqueue: threads and sockets both waiting??\n");
 
@@ -161,73 +178,79 @@ svc_sock_enqueue(struct svc_sock *svsk)
                goto out_unlock;
        }
 
-       if (test_bit(SK_BUSY, &svsk->sk_flags)) {
-               /* Don't enqueue socket while daemon is receiving */
+       /* Mark socket as busy. It will remain in this state until the
+        * server has processed all pending data and put the socket back
+        * on the idle list.  We update SK_BUSY atomically because
+        * it also guards against trying to enqueue the svc_sock twice.
+        */
+       if (test_and_set_bit(SK_BUSY, &svsk->sk_flags)) {
+               /* Don't enqueue socket while already enqueued */
                dprintk("svc: socket %p busy, not enqueued\n", svsk->sk_sk);
                goto out_unlock;
        }
+       BUG_ON(svsk->sk_pool != NULL);
+       svsk->sk_pool = pool;
 
        set_bit(SOCK_NOSPACE, &svsk->sk_sock->flags);
-       if (((svsk->sk_reserved + serv->sv_bufsz)*2
+       if (((atomic_read(&svsk->sk_reserved) + serv->sv_bufsz)*2
             > svc_sock_wspace(svsk))
            && !test_bit(SK_CLOSE, &svsk->sk_flags)
            && !test_bit(SK_CONN, &svsk->sk_flags)) {
                /* Don't enqueue while not enough space for reply */
                dprintk("svc: socket %p  no space, %d*2 > %ld, not enqueued\n",
-                       svsk->sk_sk, svsk->sk_reserved+serv->sv_bufsz,
+                       svsk->sk_sk, atomic_read(&svsk->sk_reserved)+serv->sv_bufsz,
                        svc_sock_wspace(svsk));
+               svsk->sk_pool = NULL;
+               clear_bit(SK_BUSY, &svsk->sk_flags);
                goto out_unlock;
        }
        clear_bit(SOCK_NOSPACE, &svsk->sk_sock->flags);
 
-       /* Mark socket as busy. It will remain in this state until the
-        * server has processed all pending data and put the socket back
-        * on the idle list.
-        */
-       set_bit(SK_BUSY, &svsk->sk_flags);
 
-       if (!list_empty(&serv->sv_threads)) {
-               rqstp = list_entry(serv->sv_threads.next,
+       if (!list_empty(&pool->sp_threads)) {
+               rqstp = list_entry(pool->sp_threads.next,
                                   struct svc_rqst,
                                   rq_list);
                dprintk("svc: socket %p served by daemon %p\n",
                        svsk->sk_sk, rqstp);
-               svc_serv_dequeue(serv, rqstp);
+               svc_thread_dequeue(pool, rqstp);
                if (rqstp->rq_sock)
                        printk(KERN_ERR 
                                "svc_sock_enqueue: server %p, rq_sock=%p!\n",
                                rqstp, rqstp->rq_sock);
                rqstp->rq_sock = svsk;
-               svsk->sk_inuse++;
+               atomic_inc(&svsk->sk_inuse);
                rqstp->rq_reserved = serv->sv_bufsz;
-               svsk->sk_reserved += rqstp->rq_reserved;
+               atomic_add(rqstp->rq_reserved, &svsk->sk_reserved);
+               BUG_ON(svsk->sk_pool != pool);
                wake_up(&rqstp->rq_wait);
        } else {
                dprintk("svc: socket %p put into queue\n", svsk->sk_sk);
-               list_add_tail(&svsk->sk_ready, &serv->sv_sockets);
+               list_add_tail(&svsk->sk_ready, &pool->sp_sockets);
+               BUG_ON(svsk->sk_pool != pool);
        }
 
 out_unlock:
-       spin_unlock_bh(&serv->sv_lock);
+       spin_unlock_bh(&pool->sp_lock);
 }
 
 /*
- * Dequeue the first socket.  Must be called with the serv->sv_lock held.
+ * Dequeue the first socket.  Must be called with the pool->sp_lock held.
  */
 static inline struct svc_sock *
-svc_sock_dequeue(struct svc_serv *serv)
+svc_sock_dequeue(struct svc_pool *pool)
 {
        struct svc_sock *svsk;
 
-       if (list_empty(&serv->sv_sockets))
+       if (list_empty(&pool->sp_sockets))
                return NULL;
 
-       svsk = list_entry(serv->sv_sockets.next,
+       svsk = list_entry(pool->sp_sockets.next,
                          struct svc_sock, sk_ready);
        list_del_init(&svsk->sk_ready);
 
        dprintk("svc: socket %p dequeued, inuse=%d\n",
-               svsk->sk_sk, svsk->sk_inuse);
+               svsk->sk_sk, atomic_read(&svsk->sk_inuse));
 
        return svsk;
 }
@@ -241,6 +264,7 @@ svc_sock_dequeue(struct svc_serv *serv)
 static inline void
 svc_sock_received(struct svc_sock *svsk)
 {
+       svsk->sk_pool = NULL;
        clear_bit(SK_BUSY, &svsk->sk_flags);
        svc_sock_enqueue(svsk);
 }
@@ -262,10 +286,8 @@ void svc_reserve(struct svc_rqst *rqstp, int space)
 
        if (space < rqstp->rq_reserved) {
                struct svc_sock *svsk = rqstp->rq_sock;
-               spin_lock_bh(&svsk->sk_server->sv_lock);
-               svsk->sk_reserved -= (rqstp->rq_reserved - space);
+               atomic_sub((rqstp->rq_reserved - space), &svsk->sk_reserved);
                rqstp->rq_reserved = space;
-               spin_unlock_bh(&svsk->sk_server->sv_lock);
 
                svc_sock_enqueue(svsk);
        }
@@ -277,17 +299,11 @@ void svc_reserve(struct svc_rqst *rqstp, int space)
 static inline void
 svc_sock_put(struct svc_sock *svsk)
 {
-       struct svc_serv *serv = svsk->sk_server;
-
-       spin_lock_bh(&serv->sv_lock);
-       if (!--(svsk->sk_inuse) && test_bit(SK_DEAD, &svsk->sk_flags)) {
-               spin_unlock_bh(&serv->sv_lock);
+       if (atomic_dec_and_test(&svsk->sk_inuse) && test_bit(SK_DEAD, &svsk->sk_flags)) {
                dprintk("svc: releasing dead socket\n");
                sock_release(svsk->sk_sock);
                kfree(svsk);
        }
-       else
-               spin_unlock_bh(&serv->sv_lock);
 }
 
 static void
@@ -297,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;
 
@@ -321,25 +337,33 @@ svc_sock_release(struct svc_rqst *rqstp)
 
 /*
  * External function to wake up a server waiting for data
+ * This really only makes sense for services like lockd
+ * which have exactly one thread anyway.
  */
 void
 svc_wake_up(struct svc_serv *serv)
 {
        struct svc_rqst *rqstp;
-
-       spin_lock_bh(&serv->sv_lock);
-       if (!list_empty(&serv->sv_threads)) {
-               rqstp = list_entry(serv->sv_threads.next,
-                                  struct svc_rqst,
-                                  rq_list);
-               dprintk("svc: daemon %p woken up.\n", rqstp);
-               /*
-               svc_serv_dequeue(serv, rqstp);
-               rqstp->rq_sock = NULL;
-                */
-               wake_up(&rqstp->rq_wait);
+       unsigned int i;
+       struct svc_pool *pool;
+
+       for (i = 0; i < serv->sv_nrpools; i++) {
+               pool = &serv->sv_pools[i];
+
+               spin_lock_bh(&pool->sp_lock);
+               if (!list_empty(&pool->sp_threads)) {
+                       rqstp = list_entry(pool->sp_threads.next,
+                                          struct svc_rqst,
+                                          rq_list);
+                       dprintk("svc: daemon %p woken up.\n", rqstp);
+                       /*
+                       svc_thread_dequeue(pool, rqstp);
+                       rqstp->rq_sock = NULL;
+                        */
+                       wake_up(&rqstp->rq_wait);
+               }
+               spin_unlock_bh(&pool->sp_lock);
        }
-       spin_unlock_bh(&serv->sv_lock);
 }
 
 /*
@@ -388,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;
@@ -413,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)
@@ -428,6 +454,56 @@ out:
        return len;
 }
 
+/*
+ * Report socket names for nfsdfs
+ */
+static int one_sock_name(char *buf, struct svc_sock *svsk)
+{
+       int len;
+
+       switch(svsk->sk_sk->sk_family) {
+       case AF_INET:
+               len = sprintf(buf, "ipv4 %s %u.%u.%u.%u %d\n",
+                             svsk->sk_sk->sk_protocol==IPPROTO_UDP?
+                             "udp" : "tcp",
+                             NIPQUAD(inet_sk(svsk->sk_sk)->rcv_saddr),
+                             inet_sk(svsk->sk_sk)->num);
+               break;
+       default:
+               len = sprintf(buf, "*unknown-%d*\n",
+                              svsk->sk_sk->sk_family);
+       }
+       return len;
+}
+
+int
+svc_sock_names(char *buf, struct svc_serv *serv, char *toclose)
+{
+       struct svc_sock *svsk, *closesk = NULL;
+       int len = 0;
+
+       if (!serv)
+               return 0;
+       spin_lock(&serv->sv_lock);
+       list_for_each_entry(svsk, &serv->sv_permsocks, sk_list) {
+               int onelen = one_sock_name(buf+len, svsk);
+               if (toclose && strcmp(toclose, buf+len) == 0)
+                       closesk = svsk;
+               else
+                       len += onelen;
+       }
+       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);
+
 /*
  * Check input queue length
  */
@@ -557,7 +633,10 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
            /* udp sockets need large rcvbuf as all pending
             * requests are still in that buffer.  sndbuf must
             * also be large enough that there is enough space
-            * for one reply per thread.
+            * for one reply per thread.  We count all threads
+            * rather than threads in a particular pool, which
+            * provides an upper bound on the number of threads
+            * which will access the socket.
             */
            svc_sock_setbufsize(svsk->sk_sock,
                                (serv->sv_nrthreads+3) * serv->sv_bufsz,
@@ -631,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)
@@ -844,7 +925,7 @@ svc_tcp_accept(struct svc_sock *svsk)
                                          struct svc_sock,
                                          sk_list);
                        set_bit(SK_CLOSE, &svsk->sk_flags);
-                       svsk->sk_inuse ++;
+                       atomic_inc(&svsk->sk_inuse);
                }
                spin_unlock_bh(&serv->sv_lock);
 
@@ -874,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",
@@ -902,6 +983,11 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp)
                /* sndbuf needs to have room for one request
                 * per thread, otherwise we can stall even when the
                 * network isn't a bottleneck.
+                *
+                * We count all threads rather than threads in a
+                * particular pool, which provides an upper bound
+                * on the number of threads which will access the socket.
+                *
                 * rcvbuf just needs to be able to hold a few requests.
                 * Normally they will be removed from the queue 
                 * as soon a a complete request arrives.
@@ -967,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);
@@ -1117,13 +1205,17 @@ svc_sock_update_bufs(struct svc_serv *serv)
 }
 
 /*
- * Receive the next request on any socket.
+ * Receive the next request on any socket.  This code is carefully
+ * organised not to touch any cachelines in the shared svc_serv
+ * structure, only cachelines in the local svc_pool.
  */
 int
-svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp, long timeout)
+svc_recv(struct svc_rqst *rqstp, long timeout)
 {
        struct svc_sock         *svsk =NULL;
-       int                     len;
+       struct svc_serv         *serv = rqstp->rq_server;
+       struct svc_pool         *pool = rqstp->rq_pool;
+       int                     len, i;
        int                     pages;
        struct xdr_buf          *arg;
        DECLARE_WAITQUEUE(wait, current);
@@ -1140,27 +1232,22 @@ svc_recv(struct svc_serv *serv, 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;
@@ -1172,32 +1259,15 @@ svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp, long timeout)
        if (signalled())
                return -EINTR;
 
-       spin_lock_bh(&serv->sv_lock);
-       if (!list_empty(&serv->sv_tempsocks)) {
-               svsk = list_entry(serv->sv_tempsocks.next,
-                                 struct svc_sock, sk_list);
-               /* apparently the "standard" is that clients close
-                * idle connections after 5 minutes, servers after
-                * 6 minutes
-                *   http://www.connectathon.org/talks96/nfstcp.pdf 
-                */
-               if (get_seconds() - svsk->sk_lastrecv < 6*60
-                   || test_bit(SK_BUSY, &svsk->sk_flags))
-                       svsk = NULL;
-       }
-       if (svsk) {
-               set_bit(SK_BUSY, &svsk->sk_flags);
-               set_bit(SK_CLOSE, &svsk->sk_flags);
-               rqstp->rq_sock = svsk;
-               svsk->sk_inuse++;
-       } else if ((svsk = svc_sock_dequeue(serv)) != NULL) {
+       spin_lock_bh(&pool->sp_lock);
+       if ((svsk = svc_sock_dequeue(pool)) != NULL) {
                rqstp->rq_sock = svsk;
-               svsk->sk_inuse++;
+               atomic_inc(&svsk->sk_inuse);
                rqstp->rq_reserved = serv->sv_bufsz;    
-               svsk->sk_reserved += rqstp->rq_reserved;
+               atomic_add(rqstp->rq_reserved, &svsk->sk_reserved);
        } else {
                /* No data pending. Go to sleep */
-               svc_serv_enqueue(serv, rqstp);
+               svc_thread_enqueue(pool, rqstp);
 
                /*
                 * We have to be able to interrupt this wait
@@ -1205,26 +1275,26 @@ svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp, long timeout)
                 */
                set_current_state(TASK_INTERRUPTIBLE);
                add_wait_queue(&rqstp->rq_wait, &wait);
-               spin_unlock_bh(&serv->sv_lock);
+               spin_unlock_bh(&pool->sp_lock);
 
                schedule_timeout(timeout);
 
                try_to_freeze();
 
-               spin_lock_bh(&serv->sv_lock);
+               spin_lock_bh(&pool->sp_lock);
                remove_wait_queue(&rqstp->rq_wait, &wait);
 
                if (!(svsk = rqstp->rq_sock)) {
-                       svc_serv_dequeue(serv, rqstp);
-                       spin_unlock_bh(&serv->sv_lock);
+                       svc_thread_dequeue(pool, rqstp);
+                       spin_unlock_bh(&pool->sp_lock);
                        dprintk("svc: server %p, no data yet\n", rqstp);
                        return signalled()? -EINTR : -EAGAIN;
                }
        }
-       spin_unlock_bh(&serv->sv_lock);
+       spin_unlock_bh(&pool->sp_lock);
 
-       dprintk("svc: server %p, socket %p, inuse=%d\n",
-                rqstp, svsk, svsk->sk_inuse);
+       dprintk("svc: server %p, pool %u, socket %p, inuse=%d\n",
+                rqstp, pool->sp_id, svsk, atomic_read(&svsk->sk_inuse));
        len = svsk->sk_recvfrom(rqstp);
        dprintk("svc: got len=%d\n", len);
 
@@ -1235,13 +1305,7 @@ svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp, long timeout)
                return -EAGAIN;
        }
        svsk->sk_lastrecv = get_seconds();
-       if (test_bit(SK_TEMP, &svsk->sk_flags)) {
-               /* push active sockets to end of list */
-               spin_lock_bh(&serv->sv_lock);
-               if (!list_empty(&svsk->sk_list))
-                       list_move_tail(&svsk->sk_list, &serv->sv_tempsocks);
-               spin_unlock_bh(&serv->sv_lock);
-       }
+       clear_bit(SK_OLD, &svsk->sk_flags);
 
        rqstp->rq_secure  = ntohs(rqstp->rq_addr.sin_port) < 1024;
        rqstp->rq_chandle.defer = svc_defer;
@@ -1300,6 +1364,58 @@ svc_send(struct svc_rqst *rqstp)
        return len;
 }
 
+/*
+ * Timer function to close old temporary sockets, using
+ * a mark-and-sweep algorithm.
+ */
+static void
+svc_age_temp_sockets(unsigned long closure)
+{
+       struct svc_serv *serv = (struct svc_serv *)closure;
+       struct svc_sock *svsk;
+       struct list_head *le, *next;
+       LIST_HEAD(to_be_aged);
+
+       dprintk("svc_age_temp_sockets\n");
+
+       if (!spin_trylock_bh(&serv->sv_lock)) {
+               /* busy, try again 1 sec later */
+               dprintk("svc_age_temp_sockets: busy\n");
+               mod_timer(&serv->sv_temptimer, jiffies + HZ);
+               return;
+       }
+
+       list_for_each_safe(le, next, &serv->sv_tempsocks) {
+               svsk = list_entry(le, struct svc_sock, sk_list);
+
+               if (!test_and_set_bit(SK_OLD, &svsk->sk_flags))
+                       continue;
+               if (atomic_read(&svsk->sk_inuse) || test_bit(SK_BUSY, &svsk->sk_flags))
+                       continue;
+               atomic_inc(&svsk->sk_inuse);
+               list_move(le, &to_be_aged);
+               set_bit(SK_CLOSE, &svsk->sk_flags);
+               set_bit(SK_DETACHED, &svsk->sk_flags);
+       }
+       spin_unlock_bh(&serv->sv_lock);
+
+       while (!list_empty(&to_be_aged)) {
+               le = to_be_aged.next;
+               /* fiddling the sk_list node is safe 'cos we're SK_DETACHED */
+               list_del_init(le);
+               svsk = list_entry(le, struct svc_sock, sk_list);
+
+               dprintk("queuing svsk %p for closing, %lu seconds old\n",
+                       svsk, get_seconds() - svsk->sk_lastrecv);
+
+               /* a thread will dequeue and close it soon */
+               svc_sock_enqueue(svsk);
+               svc_sock_put(svsk);
+       }
+
+       mod_timer(&serv->sv_temptimer, jiffies + svc_conn_age_period * HZ);
+}
+
 /*
  * Initialize socket for RPC use and create svc_sock struct
  * XXX: May want to setsockopt SO_SNDBUF and SO_RCVBUF.
@@ -1337,7 +1453,9 @@ svc_setup_socket(struct svc_serv *serv, struct socket *sock,
        svsk->sk_odata = inet->sk_data_ready;
        svsk->sk_owspace = inet->sk_write_space;
        svsk->sk_server = serv;
+       atomic_set(&svsk->sk_inuse, 0);
        svsk->sk_lastrecv = get_seconds();
+       spin_lock_init(&svsk->sk_defer_lock);
        INIT_LIST_HEAD(&svsk->sk_deferred);
        INIT_LIST_HEAD(&svsk->sk_ready);
        mutex_init(&svsk->sk_mutex);
@@ -1353,6 +1471,13 @@ svc_setup_socket(struct svc_serv *serv, struct socket *sock,
                set_bit(SK_TEMP, &svsk->sk_flags);
                list_add(&svsk->sk_list, &serv->sv_tempsocks);
                serv->sv_tmpcnt++;
+               if (serv->sv_temptimer.function == NULL) {
+                       /* setup timer to age temp sockets */
+                       setup_timer(&serv->sv_temptimer, svc_age_temp_sockets,
+                                       (unsigned long)serv);
+                       mod_timer(&serv->sv_temptimer,
+                                       jiffies + svc_conn_age_period * HZ);
+               }
        } else {
                clear_bit(SK_TEMP, &svsk->sk_flags);
                list_add(&svsk->sk_list, &serv->sv_permsocks);
@@ -1367,6 +1492,38 @@ svc_setup_socket(struct svc_serv *serv, struct socket *sock,
        return svsk;
 }
 
+int svc_addsock(struct svc_serv *serv,
+               int fd,
+               char *name_return,
+               int *proto)
+{
+       int err = 0;
+       struct socket *so = sockfd_lookup(fd, &err);
+       struct svc_sock *svsk = NULL;
+
+       if (!so)
+               return err;
+       if (so->sk->sk_family != AF_INET)
+               err =  -EAFNOSUPPORT;
+       else if (so->sk->sk_protocol != IPPROTO_TCP &&
+           so->sk->sk_protocol != IPPROTO_UDP)
+               err =  -EPROTONOSUPPORT;
+       else if (so->state > SS_UNCONNECTED)
+               err = -EISCONN;
+       else {
+               svsk = svc_setup_socket(serv, so, &err, 1);
+               if (svsk)
+                       err = 0;
+       }
+       if (err) {
+               sockfd_put(so);
+               return err;
+       }
+       if (proto) *proto = so->sk->sk_protocol;
+       return one_sock_name(name_return, svsk);
+}
+EXPORT_SYMBOL_GPL(svc_addsock);
+
 /*
  * Create socket for RPC service.
  */
@@ -1434,15 +1591,27 @@ svc_delete_socket(struct svc_sock *svsk)
 
        spin_lock_bh(&serv->sv_lock);
 
-       list_del_init(&svsk->sk_list);
-       list_del_init(&svsk->sk_ready);
+       if (!test_and_set_bit(SK_DETACHED, &svsk->sk_flags))
+               list_del_init(&svsk->sk_list);
+       /*
+        * We used to delete the svc_sock from whichever list
+        * it's sk_ready node was on, but we don't actually
+        * need to.  This is because the only time we're called
+        * while still attached to a queue, the queue itself
+        * is about to be destroyed (in svc_destroy).
+        */
        if (!test_and_set_bit(SK_DEAD, &svsk->sk_flags))
                if (test_bit(SK_TEMP, &svsk->sk_flags))
                        serv->sv_tmpcnt--;
 
-       if (!svsk->sk_inuse) {
+       if (!atomic_read(&svsk->sk_inuse)) {
                spin_unlock_bh(&serv->sv_lock);
-               sock_release(svsk->sk_sock);
+               if (svsk->sk_sock->file)
+                       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);
@@ -1473,7 +1642,6 @@ svc_makesock(struct svc_serv *serv, int protocol, unsigned short port)
 static void svc_revisit(struct cache_deferred_req *dreq, int too_many)
 {
        struct svc_deferred_req *dr = container_of(dreq, struct svc_deferred_req, handle);
-       struct svc_serv *serv = dreq->owner;
        struct svc_sock *svsk;
 
        if (too_many) {
@@ -1484,9 +1652,9 @@ static void svc_revisit(struct cache_deferred_req *dreq, int too_many)
        dprintk("revisit queued\n");
        svsk = dr->svsk;
        dr->svsk = NULL;
-       spin_lock_bh(&serv->sv_lock);
+       spin_lock_bh(&svsk->sk_defer_lock);
        list_add(&dr->handle.recent, &svsk->sk_deferred);
-       spin_unlock_bh(&serv->sv_lock);
+       spin_unlock_bh(&svsk->sk_defer_lock);
        set_bit(SK_DEFERRED, &svsk->sk_flags);
        svc_sock_enqueue(svsk);
        svc_sock_put(svsk);
@@ -1518,10 +1686,8 @@ svc_defer(struct cache_req *req)
                dr->argslen = rqstp->rq_arg.len >> 2;
                memcpy(dr->args, rqstp->rq_arg.head[0].iov_base-skip, dr->argslen<<2);
        }
-       spin_lock_bh(&rqstp->rq_server->sv_lock);
-       rqstp->rq_sock->sk_inuse++;
+       atomic_inc(&rqstp->rq_sock->sk_inuse);
        dr->svsk = rqstp->rq_sock;
-       spin_unlock_bh(&rqstp->rq_server->sv_lock);
 
        dr->handle.revisit = svc_revisit;
        return &dr->handle;
@@ -1541,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;
 }
 
@@ -1548,11 +1715,10 @@ static int svc_deferred_recv(struct svc_rqst *rqstp)
 static struct svc_deferred_req *svc_deferred_dequeue(struct svc_sock *svsk)
 {
        struct svc_deferred_req *dr = NULL;
-       struct svc_serv *serv = svsk->sk_server;
        
        if (!test_bit(SK_DEFERRED, &svsk->sk_flags))
                return NULL;
-       spin_lock_bh(&serv->sv_lock);
+       spin_lock_bh(&svsk->sk_defer_lock);
        clear_bit(SK_DEFERRED, &svsk->sk_flags);
        if (!list_empty(&svsk->sk_deferred)) {
                dr = list_entry(svsk->sk_deferred.next,
@@ -1561,6 +1727,6 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_sock *svsk)
                list_del_init(&dr->handle.recent);
                set_bit(SK_DEFERRED, &svsk->sk_flags);
        }
-       spin_unlock_bh(&serv->sv_lock);
+       spin_unlock_bh(&svsk->sk_defer_lock);
        return dr;
 }
index 693f02eca6d68226966c02642b4396d013849d05..53bc8cb5adbc7bc98e2ede758f89e7ba3b1d05c4 100644 (file)
@@ -1666,8 +1666,9 @@ static void link_retransmit_failure(struct link *l_ptr, struct sk_buff *buf)
                char addr_string[16];
 
                tipc_printf(TIPC_OUTPUT, "Msg seq number: %u,  ", msg_seqno(msg));
-               tipc_printf(TIPC_OUTPUT, "Outstanding acks: %u\n", (u32)TIPC_SKB_CB(buf)->handle);
-               
+               tipc_printf(TIPC_OUTPUT, "Outstanding acks: %lu\n",
+                                    (unsigned long) TIPC_SKB_CB(buf)->handle);
+
                n_ptr = l_ptr->owner->next;
                tipc_node_lock(n_ptr);
 
index 6ac4e4f033aca67e1d7178efb4347c98a672aa1b..d401dc8f05ed4b16ddde802bf3d2190d72cd2cf3 100644 (file)
@@ -41,17 +41,18 @@ static inline unsigned int __xfrm_dst_hash(xfrm_address_t *daddr, xfrm_address_t
        return (h ^ (h >> 16)) & hmask;
 }
 
-static inline unsigned __xfrm_src_hash(xfrm_address_t *saddr,
+static inline unsigned __xfrm_src_hash(xfrm_address_t *daddr,
+                                      xfrm_address_t *saddr,
                                       unsigned short family,
                                       unsigned int hmask)
 {
        unsigned int h = family;
        switch (family) {
        case AF_INET:
-               h ^= __xfrm4_addr_hash(saddr);
+               h ^= __xfrm4_daddr_saddr_hash(daddr, saddr);
                break;
        case AF_INET6:
-               h ^= __xfrm6_addr_hash(saddr);
+               h ^= __xfrm6_daddr_saddr_hash(daddr, saddr);
                break;
        };
        return (h ^ (h >> 16)) & hmask;
index b6e2e79d72612be4f99d82d3b8eb7027010c386b..2a7861661f14e5f268fd376117bdd70367165893 100644 (file)
@@ -778,8 +778,9 @@ void xfrm_policy_flush(u8 type)
        for (dir = 0; dir < XFRM_POLICY_MAX; dir++) {
                struct xfrm_policy *pol;
                struct hlist_node *entry;
-               int i;
+               int i, killed;
 
+               killed = 0;
        again1:
                hlist_for_each_entry(pol, entry,
                                     &xfrm_policy_inexact[dir], bydst) {
@@ -790,6 +791,7 @@ void xfrm_policy_flush(u8 type)
                        write_unlock_bh(&xfrm_policy_lock);
 
                        xfrm_policy_kill(pol);
+                       killed++;
 
                        write_lock_bh(&xfrm_policy_lock);
                        goto again1;
@@ -807,13 +809,14 @@ void xfrm_policy_flush(u8 type)
                                write_unlock_bh(&xfrm_policy_lock);
 
                                xfrm_policy_kill(pol);
+                               killed++;
 
                                write_lock_bh(&xfrm_policy_lock);
                                goto again2;
                        }
                }
 
-               xfrm_policy_count[dir] = 0;
+               xfrm_policy_count[dir] -= killed;
        }
        atomic_inc(&flow_cache_genid);
        write_unlock_bh(&xfrm_policy_lock);
index f927b7330f025cca4c05ed0dd7157edd2723924e..39b8bf3a9ded2c7d92b61f8477e138c772c45d3f 100644 (file)
@@ -63,10 +63,11 @@ static inline unsigned int xfrm_dst_hash(xfrm_address_t *daddr,
        return __xfrm_dst_hash(daddr, saddr, reqid, family, xfrm_state_hmask);
 }
 
-static inline unsigned int xfrm_src_hash(xfrm_address_t *addr,
+static inline unsigned int xfrm_src_hash(xfrm_address_t *daddr,
+                                        xfrm_address_t *saddr,
                                         unsigned short family)
 {
-       return __xfrm_src_hash(addr, family, xfrm_state_hmask);
+       return __xfrm_src_hash(daddr, saddr, family, xfrm_state_hmask);
 }
 
 static inline unsigned int
@@ -92,7 +93,8 @@ static void xfrm_hash_transfer(struct hlist_head *list,
                                    nhashmask);
                hlist_add_head(&x->bydst, ndsttable+h);
 
-               h = __xfrm_src_hash(&x->props.saddr, x->props.family,
+               h = __xfrm_src_hash(&x->id.daddr, &x->props.saddr,
+                                   x->props.family,
                                    nhashmask);
                hlist_add_head(&x->bysrc, nsrctable+h);
 
@@ -458,7 +460,7 @@ static struct xfrm_state *__xfrm_state_lookup(xfrm_address_t *daddr, __be32 spi,
 
 static struct xfrm_state *__xfrm_state_lookup_byaddr(xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family)
 {
-       unsigned int h = xfrm_src_hash(saddr, family);
+       unsigned int h = xfrm_src_hash(daddr, saddr, family);
        struct xfrm_state *x;
        struct hlist_node *entry;
 
@@ -587,7 +589,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
                if (km_query(x, tmpl, pol) == 0) {
                        x->km.state = XFRM_STATE_ACQ;
                        hlist_add_head(&x->bydst, xfrm_state_bydst+h);
-                       h = xfrm_src_hash(saddr, family);
+                       h = xfrm_src_hash(daddr, saddr, family);
                        hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
                        if (x->id.spi) {
                                h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, family);
@@ -622,7 +624,7 @@ static void __xfrm_state_insert(struct xfrm_state *x)
                          x->props.reqid, x->props.family);
        hlist_add_head(&x->bydst, xfrm_state_bydst+h);
 
-       h = xfrm_src_hash(&x->props.saddr, x->props.family);
+       h = xfrm_src_hash(&x->id.daddr, &x->props.saddr, x->props.family);
        hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
 
        if (x->id.spi) {
@@ -748,7 +750,7 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re
                x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ;
                add_timer(&x->timer);
                hlist_add_head(&x->bydst, xfrm_state_bydst+h);
-               h = xfrm_src_hash(saddr, family);
+               h = xfrm_src_hash(daddr, saddr, family);
                hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
                wake_up(&km_waitq);
        }
index c59a78d2923a5baf23061e8f693d3114b8120109..d54b3a70d5dfb6cda89a8661a0ee380c078d791d 100644 (file)
@@ -211,6 +211,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
        case XFRM_MODE_TRANSPORT:
        case XFRM_MODE_TUNNEL:
        case XFRM_MODE_ROUTEOPTIMIZATION:
+       case XFRM_MODE_BEET:
                break;
 
        default:
index a234e524a4901ad05c11a818575ed23e82c1e265..a1f52cb47200990d9da983c204319954ff4e0a18 100644 (file)
@@ -5,3 +5,4 @@ conmakehash
 kallsyms
 pnmtologo
 bin2c
+unifdef
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 4b2721ca97da3af2e51e58392acdb8c6fe674b84..6c5469b1473bee648984676165942cebed2b5971 100644 (file)
 # Step 4 is solely used to allow module versioning in external modules,
 # where the CRC of each module is retrieved from the Module.symers file.
 
+# KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined
+# symbols in the final module linking stage
+# KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules.
+# This is solely usefull to speed up test compiles
 PHONY := _modpost
 _modpost: __modpost
 
@@ -46,7 +50,8 @@ modulesymfile := $(KBUILD_EXTMOD)/Module.symvers
 __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
 modules   := $(patsubst %.o,%.ko, $(wildcard $(__modules:.ko=.o)))
 
-_modpost: $(modules)
+# Stop after building .o files if NOFINAL is set. Makes compile tests quicker
+_modpost: $(if $(KBUILD_MODPOST_NOFINAL), $(modules:.ko:.o),$(modules))
 
 
 # Step 2), invoke modpost
@@ -58,7 +63,7 @@ quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules
        $(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \
        $(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \
        $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \
-       $(if $(KBUILD_EXTMOD),-w) \
+       $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) \
        $(wildcard vmlinux) $(filter-out FORCE,$^)
 
 PHONY += __modpost
@@ -92,7 +97,7 @@ targets += $(modules:.ko=.mod.o)
 
 # Step 6), final link of the modules
 quiet_cmd_ld_ko_o = LD [M]  $@
-      cmd_ld_ko_o = $(LD) $(LDFLAGS) $(LDFLAGS_MODULE) -o $@           \
+      cmd_ld_ko_o = $(LD) $(LDFLAGS) $(LDFLAGS_MODULE) -o $@           \
                          $(filter-out FORCE,$^)
 
 $(modules): %.ko :%.o %.mod.o FORCE
index a90d3cc76bfaf7839eef3e480b0558a5431251ab..7e7e147875bf0d01b453a65f2b037dcae20ef345 100644 (file)
@@ -11,7 +11,6 @@ gconfig: $(obj)/gconf
        $< arch/$(ARCH)/Kconfig
 
 menuconfig: $(obj)/mconf
-       $(Q)$(MAKE) $(build)=scripts/kconfig/lxdialog
        $< arch/$(ARCH)/Kconfig
 
 config: $(obj)/conf
@@ -81,6 +80,23 @@ help:
        @echo  '  allyesconfig    - New config where all options are accepted with yes'
        @echo  '  allnoconfig     - New config where all options are answered with no'
 
+# lxdialog stuff
+check-lxdialog  := $(srctree)/$(src)/lxdialog/check-lxdialog.sh
+
+# Use reursively expanded variables so we do not call gcc unless
+# we really need to do so. (Do not call gcc as part of make mrproper)
+HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags)
+HOST_LOADLIBES   = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
+
+HOST_EXTRACFLAGS += -DLOCALE
+
+PHONY += $(obj)/dochecklxdialog
+$(obj)/dochecklxdialog:
+       $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_LOADLIBES)
+
+always := dochecklxdialog
+
+
 # ===========================================================================
 # Shared Makefile for the various kconfig executables:
 # conf:          Used for defconfig, oldconfig and related targets
@@ -92,11 +108,19 @@ help:
 #         Based on GTK which needs to be installed to compile it
 # object files used by all kconfig flavours
 
-hostprogs-y    := conf mconf qconf gconf kxgettext
+lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o
+lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o
+
 conf-objs      := conf.o  zconf.tab.o
-mconf-objs     := mconf.o zconf.tab.o
+mconf-objs     := mconf.o zconf.tab.o $(lxdialog)
 kxgettext-objs := kxgettext.o zconf.tab.o
 
+hostprogs-y := conf qconf gconf kxgettext
+
+ifeq ($(MAKECMDGOALS),menuconfig)
+       hostprogs-y += mconf
+endif
+
 ifeq ($(MAKECMDGOALS),xconfig)
        qconf-target := 1
 endif
@@ -116,7 +140,6 @@ endif
 
 clean-files    := lkc_defs.h qconf.moc .tmp_qtcheck \
                   .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c
-subdir- += lxdialog
 
 # Needed for systems without gettext
 KBUILD_HAVE_NLS := $(shell \
index 69f96b398c22848d39d31907adb43505884a361a..66b15ef029313468b3918a3dcf89ae1dd65c9aa2 100644 (file)
@@ -517,7 +517,7 @@ int conf_write(const char *name)
        fclose(out);
 
        if (*tmpname) {
-               strcat(dirname, name ? name : conf_get_configname());
+               strcat(dirname, basename);
                strcat(dirname, ".old");
                rename(newname, dirname);
                if (rename(tmpname, newname))
diff --git a/scripts/kconfig/lxdialog/Makefile b/scripts/kconfig/lxdialog/Makefile
deleted file mode 100644 (file)
index a8b0263..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-# Makefile to build lxdialog package
-#
-
-check-lxdialog  := $(srctree)/$(src)/check-lxdialog.sh
-
-# Use reursively expanded variables so we do not call gcc unless
-# we really need to do so. (Do not call gcc as part of make mrproper)
-HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags)
-HOST_LOADLIBES   = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
-
-HOST_EXTRACFLAGS += -DLOCALE
-
-PHONY += dochecklxdialog
-$(obj)/dochecklxdialog:
-       $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_LOADLIBES)
-
-hostprogs-y    := lxdialog
-always         := $(hostprogs-y) dochecklxdialog
-
-lxdialog-objs := checklist.o menubox.o textbox.o yesno.o inputbox.o \
-                util.o lxdialog.o msgbox.o
index 79886413b6d52736689e29f8b5a5cd8e4a9c7532..cf697080ddddd4bf47df0057f860ef681255ea29 100644 (file)
@@ -28,25 +28,25 @@ static int list_width, check_x, item_x;
 /*
  * Print list item
  */
-static void print_item(WINDOW * win, const char *item, int status, int choice,
-                      int selected)
+static void print_item(WINDOW * win, int choice, int selected)
 {
        int i;
 
        /* Clear 'residue' of last item */
-       wattrset(win, menubox_attr);
+       wattrset(win, dlg.menubox.atr);
        wmove(win, choice, 0);
        for (i = 0; i < list_width; i++)
                waddch(win, ' ');
 
        wmove(win, choice, check_x);
-       wattrset(win, selected ? check_selected_attr : check_attr);
-       wprintw(win, "(%c)", status ? 'X' : ' ');
-
-       wattrset(win, selected ? tag_selected_attr : tag_attr);
-       mvwaddch(win, choice, item_x, item[0]);
-       wattrset(win, selected ? item_selected_attr : item_attr);
-       waddstr(win, (char *)item + 1);
+       wattrset(win, selected ? dlg.check_selected.atr
+                : dlg.check.atr);
+       wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' ');
+
+       wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr);
+       mvwaddch(win, choice, item_x, item_str()[0]);
+       wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
+       waddstr(win, (char *)item_str() + 1);
        if (selected) {
                wmove(win, choice, check_x + 1);
                wrefresh(win);
@@ -62,11 +62,11 @@ static void print_arrows(WINDOW * win, int choice, int item_no, int scroll,
        wmove(win, y, x);
 
        if (scroll > 0) {
-               wattrset(win, uarrow_attr);
+               wattrset(win, dlg.uarrow.atr);
                waddch(win, ACS_UARROW);
                waddstr(win, "(-)");
        } else {
-               wattrset(win, menubox_attr);
+               wattrset(win, dlg.menubox.atr);
                waddch(win, ACS_HLINE);
                waddch(win, ACS_HLINE);
                waddch(win, ACS_HLINE);
@@ -77,11 +77,11 @@ static void print_arrows(WINDOW * win, int choice, int item_no, int scroll,
        wmove(win, y, x);
 
        if ((height < item_no) && (scroll + choice < item_no - 1)) {
-               wattrset(win, darrow_attr);
+               wattrset(win, dlg.darrow.atr);
                waddch(win, ACS_DARROW);
                waddstr(win, "(+)");
        } else {
-               wattrset(win, menubox_border_attr);
+               wattrset(win, dlg.menubox_border.atr);
                waddch(win, ACS_HLINE);
                waddch(win, ACS_HLINE);
                waddch(win, ACS_HLINE);
@@ -109,32 +109,29 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
  * in the style of radiolist (only one option turned on at a time).
  */
 int dialog_checklist(const char *title, const char *prompt, int height,
-                    int width, int list_height, int item_no,
-                    const char *const *items)
+                    int width, int list_height)
 {
        int i, x, y, box_x, box_y;
-       int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status;
+       int key = 0, button = 0, choice = 0, scroll = 0, max_choice;
        WINDOW *dialog, *list;
 
-       /* Allocate space for storing item on/off status */
-       if ((status = malloc(sizeof(int) * item_no)) == NULL) {
-               endwin();
-               fprintf(stderr,
-                       "\nCan't allocate memory in dialog_checklist().\n");
-               exit(-1);
+       /* which item to highlight */
+       item_foreach() {
+               if (item_is_tag('X'))
+                       choice = item_n();
+               if (item_is_selected()) {
+                       choice = item_n();
+                       break;
+               }
        }
 
-       /* Initializes status */
-       for (i = 0; i < item_no; i++) {
-               status[i] = !strcasecmp(items[i * 3 + 2], "on");
-               if ((!choice && status[i])
-                   || !strcasecmp(items[i * 3 + 2], "selected"))
-                       choice = i + 1;
-       }
-       if (choice)
-               choice--;
+do_resize:
+       if (getmaxy(stdscr) < (height + 6))
+               return -ERRDISPLAYTOOSMALL;
+       if (getmaxx(stdscr) < (width + 6))
+               return -ERRDISPLAYTOOSMALL;
 
-       max_choice = MIN(list_height, item_no);
+       max_choice = MIN(list_height, item_count());
 
        /* center dialog box on screen */
        x = (COLS - width) / 2;
@@ -145,17 +142,18 @@ int dialog_checklist(const char *title, const char *prompt, int height,
        dialog = newwin(height, width, y, x);
        keypad(dialog, TRUE);
 
-       draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
-       wattrset(dialog, border_attr);
+       draw_box(dialog, 0, 0, height, width,
+                dlg.dialog.atr, dlg.border.atr);
+       wattrset(dialog, dlg.border.atr);
        mvwaddch(dialog, height - 3, 0, ACS_LTEE);
        for (i = 0; i < width - 2; i++)
                waddch(dialog, ACS_HLINE);
-       wattrset(dialog, dialog_attr);
+       wattrset(dialog, dlg.dialog.atr);
        waddch(dialog, ACS_RTEE);
 
        print_title(dialog, title, width);
 
-       wattrset(dialog, dialog_attr);
+       wattrset(dialog, dlg.dialog.atr);
        print_autowrap(dialog, prompt, width - 2, 1, 3);
 
        list_width = width - 6;
@@ -170,12 +168,12 @@ int dialog_checklist(const char *title, const char *prompt, int height,
 
        /* draw a box around the list items */
        draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2,
-                menubox_border_attr, menubox_attr);
+                dlg.menubox_border.atr, dlg.menubox.atr);
 
        /* Find length of longest item in order to center checklist */
        check_x = 0;
-       for (i = 0; i < item_no; i++)
-               check_x = MAX(check_x, +strlen(items[i * 3 + 1]) + 4);
+       item_foreach()
+               check_x = MAX(check_x, strlen(item_str()) + 4);
 
        check_x = (list_width - check_x) / 2;
        item_x = check_x + 4;
@@ -187,14 +185,11 @@ int dialog_checklist(const char *title, const char *prompt, int height,
 
        /* Print the list */
        for (i = 0; i < max_choice; i++) {
-               if (i != choice)
-                       print_item(list, items[(scroll + i) * 3 + 1],
-                                  status[i + scroll], i, 0);
+               item_set(scroll + i);
+               print_item(list, i, i == choice);
        }
-       print_item(list, items[(scroll + choice) * 3 + 1],
-                  status[choice + scroll], choice, 1);
 
-       print_arrows(dialog, choice, item_no, scroll,
+       print_arrows(dialog, choice, item_count(), scroll,
                     box_y, box_x + check_x + 5, list_height);
 
        print_buttons(dialog, height, width, 0);
@@ -203,13 +198,14 @@ int dialog_checklist(const char *title, const char *prompt, int height,
        wnoutrefresh(list);
        doupdate();
 
-       while (key != ESC) {
+       while (key != KEY_ESC) {
                key = wgetch(dialog);
 
-               for (i = 0; i < max_choice; i++)
-                       if (toupper(key) ==
-                           toupper(items[(scroll + i) * 3 + 1][0]))
+               for (i = 0; i < max_choice; i++) {
+                       item_set(i + scroll);
+                       if (toupper(key) == toupper(item_str()[0]))
                                break;
+               }
 
                if (i < max_choice || key == KEY_UP || key == KEY_DOWN ||
                    key == '+' || key == '-') {
@@ -220,15 +216,16 @@ int dialog_checklist(const char *title, const char *prompt, int height,
                                        /* Scroll list down */
                                        if (list_height > 1) {
                                                /* De-highlight current first item */
-                                               print_item(list, items[scroll * 3 + 1],
-                                                          status[scroll], 0, FALSE);
+                                               item_set(scroll);
+                                               print_item(list, 0, FALSE);
                                                scrollok(list, TRUE);
                                                wscrl(list, -1);
                                                scrollok(list, FALSE);
                                        }
                                        scroll--;
-                                       print_item(list, items[scroll * 3 + 1], status[scroll], 0, TRUE);
-                                       print_arrows(dialog, choice, item_no,
+                                       item_set(scroll);
+                                       print_item(list, 0, TRUE);
+                                       print_arrows(dialog, choice, item_count(),
                                                     scroll, box_y, box_x + check_x + 5, list_height);
 
                                        wnoutrefresh(dialog);
@@ -239,23 +236,24 @@ int dialog_checklist(const char *title, const char *prompt, int height,
                                        i = choice - 1;
                        } else if (key == KEY_DOWN || key == '+') {
                                if (choice == max_choice - 1) {
-                                       if (scroll + choice >= item_no - 1)
+                                       if (scroll + choice >= item_count() - 1)
                                                continue;
                                        /* Scroll list up */
                                        if (list_height > 1) {
                                                /* De-highlight current last item before scrolling up */
-                                               print_item(list, items[(scroll + max_choice - 1) * 3 + 1],
-                                                          status[scroll + max_choice - 1],
-                                                          max_choice - 1, FALSE);
+                                               item_set(scroll + max_choice - 1);
+                                               print_item(list,
+                                                           max_choice - 1,
+                                                           FALSE);
                                                scrollok(list, TRUE);
                                                wscrl(list, 1);
                                                scrollok(list, FALSE);
                                        }
                                        scroll++;
-                                       print_item(list, items[(scroll + max_choice - 1) * 3 + 1],
-                                                  status[scroll + max_choice - 1], max_choice - 1, TRUE);
+                                       item_set(scroll + max_choice - 1);
+                                       print_item(list, max_choice - 1, TRUE);
 
-                                       print_arrows(dialog, choice, item_no,
+                                       print_arrows(dialog, choice, item_count(),
                                                     scroll, box_y, box_x + check_x + 5, list_height);
 
                                        wnoutrefresh(dialog);
@@ -267,12 +265,12 @@ int dialog_checklist(const char *title, const char *prompt, int height,
                        }
                        if (i != choice) {
                                /* De-highlight current item */
-                               print_item(list, items[(scroll + choice) * 3 + 1],
-                                          status[scroll + choice], choice, FALSE);
+                               item_set(scroll + choice);
+                               print_item(list, choice, FALSE);
                                /* Highlight new item */
                                choice = i;
-                               print_item(list, items[(scroll + choice) * 3 + 1],
-                                          status[scroll + choice], choice, TRUE);
+                               item_set(scroll + choice);
+                               print_item(list, choice, TRUE);
                                wnoutrefresh(dialog);
                                wrefresh(list);
                        }
@@ -282,10 +280,19 @@ int dialog_checklist(const char *title, const char *prompt, int height,
                case 'H':
                case 'h':
                case '?':
-                       fprintf(stderr, "%s", items[(scroll + choice) * 3]);
+                       button = 1;
+                       /* fall-through */
+               case 'S':
+               case 's':
+               case ' ':
+               case '\n':
+                       item_foreach()
+                               item_set_selected(0);
+                       item_set(scroll + choice);
+                       item_set_selected(1);
+                       delwin(list);
                        delwin(dialog);
-                       free(status);
-                       return 1;
+                       return button;
                case TAB:
                case KEY_LEFT:
                case KEY_RIGHT:
@@ -295,42 +302,24 @@ int dialog_checklist(const char *title, const char *prompt, int height,
                        print_buttons(dialog, height, width, button);
                        wrefresh(dialog);
                        break;
-               case 'S':
-               case 's':
-               case ' ':
-               case '\n':
-                       if (!button) {
-                               if (!status[scroll + choice]) {
-                                       for (i = 0; i < item_no; i++)
-                                               status[i] = 0;
-                                       status[scroll + choice] = 1;
-                                       for (i = 0; i < max_choice; i++)
-                                               print_item(list, items[(scroll + i) * 3 + 1],
-                                                          status[scroll + i], i, i == choice);
-                               }
-                               wnoutrefresh(dialog);
-                               wrefresh(list);
-
-                               for (i = 0; i < item_no; i++)
-                                       if (status[i])
-                                               fprintf(stderr, "%s", items[i * 3]);
-                       } else
-                               fprintf(stderr, "%s", items[(scroll + choice) * 3]);
-                       delwin(dialog);
-                       free(status);
-                       return button;
                case 'X':
                case 'x':
-                       key = ESC;
-               case ESC:
+                       key = KEY_ESC;
+                       break;
+               case KEY_ESC:
+                       key = on_key_esc(dialog);
                        break;
+               case KEY_RESIZE:
+                       delwin(list);
+                       delwin(dialog);
+                       on_key_resize();
+                       goto do_resize;
                }
 
                /* Now, update everything... */
                doupdate();
        }
-
+       delwin(list);
        delwin(dialog);
-       free(status);
-       return -1;              /* ESC pressed */
+       return key;             /* ESC pressed */
 }
diff --git a/scripts/kconfig/lxdialog/colors.h b/scripts/kconfig/lxdialog/colors.h
deleted file mode 100644 (file)
index db071df..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- *  colors.h -- color attribute definitions
- *
- *  AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *
- *  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.
- */
-
-/*
- *   Default color definitions
- *
- *   *_FG = foreground
- *   *_BG = background
- *   *_HL = highlight?
- */
-#define SCREEN_FG                    COLOR_CYAN
-#define SCREEN_BG                    COLOR_BLUE
-#define SCREEN_HL                    TRUE
-
-#define SHADOW_FG                    COLOR_BLACK
-#define SHADOW_BG                    COLOR_BLACK
-#define SHADOW_HL                    TRUE
-
-#define DIALOG_FG                    COLOR_BLACK
-#define DIALOG_BG                    COLOR_WHITE
-#define DIALOG_HL                    FALSE
-
-#define TITLE_FG                     COLOR_YELLOW
-#define TITLE_BG                     COLOR_WHITE
-#define TITLE_HL                     TRUE
-
-#define BORDER_FG                    COLOR_WHITE
-#define BORDER_BG                    COLOR_WHITE
-#define BORDER_HL                    TRUE
-
-#define BUTTON_ACTIVE_FG             COLOR_WHITE
-#define BUTTON_ACTIVE_BG             COLOR_BLUE
-#define BUTTON_ACTIVE_HL             TRUE
-
-#define BUTTON_INACTIVE_FG           COLOR_BLACK
-#define BUTTON_INACTIVE_BG           COLOR_WHITE
-#define BUTTON_INACTIVE_HL           FALSE
-
-#define BUTTON_KEY_ACTIVE_FG         COLOR_WHITE
-#define BUTTON_KEY_ACTIVE_BG         COLOR_BLUE
-#define BUTTON_KEY_ACTIVE_HL         TRUE
-
-#define BUTTON_KEY_INACTIVE_FG       COLOR_RED
-#define BUTTON_KEY_INACTIVE_BG       COLOR_WHITE
-#define BUTTON_KEY_INACTIVE_HL       FALSE
-
-#define BUTTON_LABEL_ACTIVE_FG       COLOR_YELLOW
-#define BUTTON_LABEL_ACTIVE_BG       COLOR_BLUE
-#define BUTTON_LABEL_ACTIVE_HL       TRUE
-
-#define BUTTON_LABEL_INACTIVE_FG     COLOR_BLACK
-#define BUTTON_LABEL_INACTIVE_BG     COLOR_WHITE
-#define BUTTON_LABEL_INACTIVE_HL     TRUE
-
-#define INPUTBOX_FG                  COLOR_BLACK
-#define INPUTBOX_BG                  COLOR_WHITE
-#define INPUTBOX_HL                  FALSE
-
-#define INPUTBOX_BORDER_FG           COLOR_BLACK
-#define INPUTBOX_BORDER_BG           COLOR_WHITE
-#define INPUTBOX_BORDER_HL           FALSE
-
-#define SEARCHBOX_FG                 COLOR_BLACK
-#define SEARCHBOX_BG                 COLOR_WHITE
-#define SEARCHBOX_HL                 FALSE
-
-#define SEARCHBOX_TITLE_FG           COLOR_YELLOW
-#define SEARCHBOX_TITLE_BG           COLOR_WHITE
-#define SEARCHBOX_TITLE_HL           TRUE
-
-#define SEARCHBOX_BORDER_FG          COLOR_WHITE
-#define SEARCHBOX_BORDER_BG          COLOR_WHITE
-#define SEARCHBOX_BORDER_HL          TRUE
-
-#define POSITION_INDICATOR_FG        COLOR_YELLOW
-#define POSITION_INDICATOR_BG        COLOR_WHITE
-#define POSITION_INDICATOR_HL        TRUE
-
-#define MENUBOX_FG                   COLOR_BLACK
-#define MENUBOX_BG                   COLOR_WHITE
-#define MENUBOX_HL                   FALSE
-
-#define MENUBOX_BORDER_FG            COLOR_WHITE
-#define MENUBOX_BORDER_BG            COLOR_WHITE
-#define MENUBOX_BORDER_HL            TRUE
-
-#define ITEM_FG                      COLOR_BLACK
-#define ITEM_BG                      COLOR_WHITE
-#define ITEM_HL                      FALSE
-
-#define ITEM_SELECTED_FG             COLOR_WHITE
-#define ITEM_SELECTED_BG             COLOR_BLUE
-#define ITEM_SELECTED_HL             TRUE
-
-#define TAG_FG                       COLOR_YELLOW
-#define TAG_BG                       COLOR_WHITE
-#define TAG_HL                       TRUE
-
-#define TAG_SELECTED_FG              COLOR_YELLOW
-#define TAG_SELECTED_BG              COLOR_BLUE
-#define TAG_SELECTED_HL              TRUE
-
-#define TAG_KEY_FG                   COLOR_YELLOW
-#define TAG_KEY_BG                   COLOR_WHITE
-#define TAG_KEY_HL                   TRUE
-
-#define TAG_KEY_SELECTED_FG          COLOR_YELLOW
-#define TAG_KEY_SELECTED_BG          COLOR_BLUE
-#define TAG_KEY_SELECTED_HL          TRUE
-
-#define CHECK_FG                     COLOR_BLACK
-#define CHECK_BG                     COLOR_WHITE
-#define CHECK_HL                     FALSE
-
-#define CHECK_SELECTED_FG            COLOR_WHITE
-#define CHECK_SELECTED_BG            COLOR_BLUE
-#define CHECK_SELECTED_HL            TRUE
-
-#define UARROW_FG                    COLOR_GREEN
-#define UARROW_BG                    COLOR_WHITE
-#define UARROW_HL                    TRUE
-
-#define DARROW_FG                    COLOR_GREEN
-#define DARROW_BG                    COLOR_WHITE
-#define DARROW_HL                    TRUE
-
-/* End of default color definitions */
-
-#define C_ATTR(x,y)                  ((x ? A_BOLD : 0) | COLOR_PAIR((y)))
-#define COLOR_NAME_LEN               10
-#define COLOR_COUNT                  8
-
-/*
- * Global variables
- */
-
-extern int color_table[][3];
index af3cf716e2156ca4c9dbada932497af069d230a6..8dea47f9d3e49a36803ed4c90223d9858a83d3de 100644 (file)
@@ -48,7 +48,7 @@
 
 #define TR(params) _tracef params
 
-#define ESC 27
+#define KEY_ESC 27
 #define TAB 9
 #define MAX_LEN 2048
 #define BUF_SIZE (10*1024)
 #define ACS_DARROW 'v'
 #endif
 
+/* error return codes */
+#define ERRDISPLAYTOOSMALL (KEY_MAX + 1)
+
 /*
- * Attribute names
+ *   Color definitions
  */
-#define screen_attr                   attributes[0]
-#define shadow_attr                   attributes[1]
-#define dialog_attr                   attributes[2]
-#define title_attr                    attributes[3]
-#define border_attr                   attributes[4]
-#define button_active_attr            attributes[5]
-#define button_inactive_attr          attributes[6]
-#define button_key_active_attr        attributes[7]
-#define button_key_inactive_attr      attributes[8]
-#define button_label_active_attr      attributes[9]
-#define button_label_inactive_attr    attributes[10]
-#define inputbox_attr                 attributes[11]
-#define inputbox_border_attr          attributes[12]
-#define searchbox_attr                attributes[13]
-#define searchbox_title_attr          attributes[14]
-#define searchbox_border_attr         attributes[15]
-#define position_indicator_attr       attributes[16]
-#define menubox_attr                  attributes[17]
-#define menubox_border_attr           attributes[18]
-#define item_attr                     attributes[19]
-#define item_selected_attr            attributes[20]
-#define tag_attr                      attributes[21]
-#define tag_selected_attr             attributes[22]
-#define tag_key_attr                  attributes[23]
-#define tag_key_selected_attr         attributes[24]
-#define check_attr                    attributes[25]
-#define check_selected_attr           attributes[26]
-#define uarrow_attr                   attributes[27]
-#define darrow_attr                   attributes[28]
-
-/* number of attributes */
-#define ATTRIBUTE_COUNT               29
+struct dialog_color {
+       chtype atr;     /* Color attribute */
+       int fg;         /* foreground */
+       int bg;         /* background */
+       int hl;         /* highlight this item */
+};
+
+struct dialog_info {
+       const char *backtitle;
+       struct dialog_color screen;
+       struct dialog_color shadow;
+       struct dialog_color dialog;
+       struct dialog_color title;
+       struct dialog_color border;
+       struct dialog_color button_active;
+       struct dialog_color button_inactive;
+       struct dialog_color button_key_active;
+       struct dialog_color button_key_inactive;
+       struct dialog_color button_label_active;
+       struct dialog_color button_label_inactive;
+       struct dialog_color inputbox;
+       struct dialog_color inputbox_border;
+       struct dialog_color searchbox;
+       struct dialog_color searchbox_title;
+       struct dialog_color searchbox_border;
+       struct dialog_color position_indicator;
+       struct dialog_color menubox;
+       struct dialog_color menubox_border;
+       struct dialog_color item;
+       struct dialog_color item_selected;
+       struct dialog_color tag;
+       struct dialog_color tag_selected;
+       struct dialog_color tag_key;
+       struct dialog_color tag_key_selected;
+       struct dialog_color check;
+       struct dialog_color check_selected;
+       struct dialog_color uarrow;
+       struct dialog_color darrow;
+};
 
 /*
  * Global variables
  */
-extern bool use_colors;
-extern bool use_shadow;
-
-extern chtype attributes[];
-
-extern const char *backtitle;
+extern struct dialog_info dlg;
+extern char dialog_input_result[];
 
 /*
  * Function prototypes
  */
-extern void create_rc(const char *filename);
-extern int parse_rc(void);
 
-void init_dialog(void);
+/* item list as used by checklist and menubox */
+void item_reset(void);
+void item_make(const char *fmt, ...);
+void item_add_str(const char *fmt, ...);
+void item_set_tag(char tag);
+void item_set_data(void *p);
+void item_set_selected(int val);
+int item_activate_selected(void);
+void *item_data(void);
+char item_tag(void);
+
+/* item list manipulation for lxdialog use */
+#define MAXITEMSTR 200
+struct dialog_item {
+       char str[MAXITEMSTR];   /* promtp displayed */
+       char tag;
+       void *data;     /* pointer to menu item - used by menubox+checklist */
+       int selected;   /* Set to 1 by dialog_*() function if selected. */
+};
+
+/* list of lialog_items */
+struct dialog_list {
+       struct dialog_item node;
+       struct dialog_list *next;
+};
+
+extern struct dialog_list *item_cur;
+extern struct dialog_list item_nil;
+extern struct dialog_list *item_head;
+
+int item_count(void);
+void item_set(int n);
+int item_n(void);
+const char *item_str(void);
+int item_is_selected(void);
+int item_is_tag(char tag);
+#define item_foreach() \
+       for (item_cur = item_head ? item_head: item_cur; \
+            item_cur && (item_cur != &item_nil); item_cur = item_cur->next)
+
+/* generic key handlers */
+int on_key_esc(WINDOW *win);
+int on_key_resize(void);
+
+void init_dialog(const char *backtitle);
+void reset_dialog(void);
 void end_dialog(void);
 void attr_clear(WINDOW * win, int height, int width, chtype attr);
 void dialog_clear(void);
-void color_setup(void);
 void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x);
 void print_button(WINDOW * win, const char *label, int y, int x, int selected);
 void print_title(WINDOW *dialog, const char *title, int width);
@@ -155,12 +203,10 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width);
 int dialog_msgbox(const char *title, const char *prompt, int height,
                  int width, int pause);
 int dialog_textbox(const char *title, const char *file, int height, int width);
-int dialog_menu(const char *title, const char *prompt, int height, int width,
-               int menu_height, const char *choice, int item_no,
-               const char *const *items);
+int dialog_menu(const char *title, const char *prompt,
+               const void *selected, int *s_scroll);
 int dialog_checklist(const char *title, const char *prompt, int height,
-                    int width, int list_height, int item_no,
-                    const char *const *items);
+                    int width, int list_height);
 extern char dialog_input_result[];
 int dialog_inputbox(const char *title, const char *prompt, int height,
                    int width, const char *init);
index 779503726b0a77b9eb08ab3f3b9d7abc921415a7..05e72066b35987dfe7037f6abd2fe29a03cb016a 100644 (file)
@@ -49,6 +49,17 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
        char *instr = dialog_input_result;
        WINDOW *dialog;
 
+       if (!init)
+               instr[0] = '\0';
+       else
+               strcpy(instr, init);
+
+do_resize:
+       if (getmaxy(stdscr) <= (height - 2))
+               return -ERRDISPLAYTOOSMALL;
+       if (getmaxx(stdscr) <= (width - 2))
+               return -ERRDISPLAYTOOSMALL;
+
        /* center dialog box on screen */
        x = (COLS - width) / 2;
        y = (LINES - height) / 2;
@@ -58,17 +69,18 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
        dialog = newwin(height, width, y, x);
        keypad(dialog, TRUE);
 
-       draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
-       wattrset(dialog, border_attr);
+       draw_box(dialog, 0, 0, height, width,
+                dlg.dialog.atr, dlg.border.atr);
+       wattrset(dialog, dlg.border.atr);
        mvwaddch(dialog, height - 3, 0, ACS_LTEE);
        for (i = 0; i < width - 2; i++)
                waddch(dialog, ACS_HLINE);
-       wattrset(dialog, dialog_attr);
+       wattrset(dialog, dlg.dialog.atr);
        waddch(dialog, ACS_RTEE);
 
        print_title(dialog, title, width);
 
-       wattrset(dialog, dialog_attr);
+       wattrset(dialog, dlg.dialog.atr);
        print_autowrap(dialog, prompt, width - 2, 1, 3);
 
        /* Draw the input field box */
@@ -76,18 +88,14 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
        getyx(dialog, y, x);
        box_y = y + 2;
        box_x = (width - box_width) / 2;
-       draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2, border_attr, dialog_attr);
+       draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2,
+                dlg.border.atr, dlg.dialog.atr);
 
        print_buttons(dialog, height, width, 0);
 
        /* Set up the initial value */
        wmove(dialog, box_y, box_x);
-       wattrset(dialog, inputbox_attr);
-
-       if (!init)
-               instr[0] = '\0';
-       else
-               strcpy(instr, init);
+       wattrset(dialog, dlg.inputbox.atr);
 
        input_x = strlen(instr);
 
@@ -104,7 +112,7 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
 
        wrefresh(dialog);
 
-       while (key != ESC) {
+       while (key != KEY_ESC) {
                key = wgetch(dialog);
 
                if (button == -1) {     /* Input box selected */
@@ -120,7 +128,7 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
                        case KEY_BACKSPACE:
                        case 127:
                                if (input_x || scroll) {
-                                       wattrset(dialog, inputbox_attr);
+                                       wattrset(dialog, dlg.inputbox.atr);
                                        if (!input_x) {
                                                scroll = scroll < box_width - 1 ? 0 : scroll - (box_width - 1);
                                                wmove(dialog, box_y, box_x);
@@ -140,7 +148,7 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
                        default:
                                if (key < 0x100 && isprint(key)) {
                                        if (scroll + input_x < MAX_LEN) {
-                                               wattrset(dialog, inputbox_attr);
+                                               wattrset(dialog, dlg.inputbox.atr);
                                                instr[scroll + input_x] = key;
                                                instr[scroll + input_x + 1] = '\0';
                                                if (input_x == box_width - 1) {
@@ -213,12 +221,18 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
                        return (button == -1 ? 0 : button);
                case 'X':
                case 'x':
-                       key = ESC;
-               case ESC:
+                       key = KEY_ESC;
+                       break;
+               case KEY_ESC:
+                       key = on_key_esc(dialog);
                        break;
+               case KEY_RESIZE:
+                       delwin(dialog);
+                       on_key_resize();
+                       goto do_resize;
                }
        }
 
        delwin(dialog);
-       return -1;              /* ESC pressed */
+       return KEY_ESC;         /* ESC pressed */
 }
diff --git a/scripts/kconfig/lxdialog/lxdialog.c b/scripts/kconfig/lxdialog/lxdialog.c
deleted file mode 100644 (file)
index 79f6c5f..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- *  dialog - Display simple dialog boxes from shell scripts
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.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.
- */
-
-#include "dialog.h"
-
-static void Usage(const char *name);
-
-typedef int (jumperFn) (const char *title, int argc, const char *const *argv);
-
-struct Mode {
-       char *name;
-       int argmin, argmax, argmod;
-       jumperFn *jumper;
-};
-
-jumperFn j_menu, j_radiolist, j_yesno, j_textbox, j_inputbox;
-jumperFn j_msgbox, j_infobox;
-
-static struct Mode modes[] = {
-       {"--menu", 9, 0, 3, j_menu},
-       {"--radiolist", 9, 0, 3, j_radiolist},
-       {"--yesno", 5, 5, 1, j_yesno},
-       {"--textbox", 5, 5, 1, j_textbox},
-       {"--inputbox", 5, 6, 1, j_inputbox},
-       {"--msgbox", 5, 5, 1, j_msgbox},
-       {"--infobox", 5, 5, 1, j_infobox},
-       {NULL, 0, 0, 0, NULL}
-};
-
-static struct Mode *modePtr;
-
-#ifdef LOCALE
-#include <locale.h>
-#endif
-
-int main(int argc, const char *const *argv)
-{
-       int offset = 0, opt_clear = 0, end_common_opts = 0, retval;
-       const char *title = NULL;
-
-#ifdef LOCALE
-       (void)setlocale(LC_ALL, "");
-#endif
-
-#ifdef TRACE
-       trace(TRACE_CALLS | TRACE_UPDATE);
-#endif
-       if (argc < 2) {
-               Usage(argv[0]);
-               exit(-1);
-       }
-
-       while (offset < argc - 1 && !end_common_opts) { /* Common options */
-               if (!strcmp(argv[offset + 1], "--title")) {
-                       if (argc - offset < 3 || title != NULL) {
-                               Usage(argv[0]);
-                               exit(-1);
-                       } else {
-                               title = argv[offset + 2];
-                               offset += 2;
-                       }
-               } else if (!strcmp(argv[offset + 1], "--backtitle")) {
-                       if (backtitle != NULL) {
-                               Usage(argv[0]);
-                               exit(-1);
-                       } else {
-                               backtitle = argv[offset + 2];
-                               offset += 2;
-                       }
-               } else if (!strcmp(argv[offset + 1], "--clear")) {
-                       if (opt_clear) {        /* Hey, "--clear" can't appear twice! */
-                               Usage(argv[0]);
-                               exit(-1);
-                       } else if (argc == 2) { /* we only want to clear the screen */
-                               init_dialog();
-                               refresh();      /* init_dialog() will clear the screen for us */
-                               end_dialog();
-                               return 0;
-                       } else {
-                               opt_clear = 1;
-                               offset++;
-                       }
-               } else          /* no more common options */
-                       end_common_opts = 1;
-       }
-
-       if (argc - 1 == offset) {       /* no more options */
-               Usage(argv[0]);
-               exit(-1);
-       }
-       /* use a table to look for the requested mode, to avoid code duplication */
-
-       for (modePtr = modes; modePtr->name; modePtr++) /* look for the mode */
-               if (!strcmp(argv[offset + 1], modePtr->name))
-                       break;
-
-       if (!modePtr->name)
-               Usage(argv[0]);
-       if (argc - offset < modePtr->argmin)
-               Usage(argv[0]);
-       if (modePtr->argmax && argc - offset > modePtr->argmax)
-               Usage(argv[0]);
-
-       init_dialog();
-       retval = (*(modePtr->jumper)) (title, argc - offset, argv + offset);
-
-       if (opt_clear) {        /* clear screen before exit */
-               attr_clear(stdscr, LINES, COLS, screen_attr);
-               refresh();
-       }
-       end_dialog();
-
-       exit(retval);
-}
-
-/*
- * Print program usage
- */
-static void Usage(const char *name)
-{
-       fprintf(stderr, "\
-\ndialog, by Savio Lam (lam836@cs.cuhk.hk).\
-\n  patched by Stuart Herbert (S.Herbert@shef.ac.uk)\
-\n  modified/gutted for use as a Linux kernel config tool by \
-\n  William Roadcap (roadcapw@cfw.com)\
-\n\
-\n* Display dialog boxes from shell scripts *\
-\n\
-\nUsage: %s --clear\
-\n       %s [--title <title>] [--backtitle <backtitle>] --clear <Box options>\
-\n\
-\nBox options:\
-\n\
-\n  --menu      <text> <height> <width> <menu height> <tag1> <item1>...\
-\n  --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
-\n  --textbox   <file> <height> <width>\
-\n  --inputbox  <text> <height> <width> [<init>]\
-\n  --yesno     <text> <height> <width>\
-\n", name, name);
-       exit(-1);
-}
-
-/*
- * These are the program jumpers
- */
-
-int j_menu(const char *t, int ac, const char *const *av)
-{
-       return dialog_menu(t, av[2], atoi(av[3]), atoi(av[4]),
-                          atoi(av[5]), av[6], (ac - 6) / 2, av + 7);
-}
-
-int j_radiolist(const char *t, int ac, const char *const *av)
-{
-       return dialog_checklist(t, av[2], atoi(av[3]), atoi(av[4]),
-                               atoi(av[5]), (ac - 6) / 3, av + 6);
-}
-
-int j_textbox(const char *t, int ac, const char *const *av)
-{
-       return dialog_textbox(t, av[2], atoi(av[3]), atoi(av[4]));
-}
-
-int j_yesno(const char *t, int ac, const char *const *av)
-{
-       return dialog_yesno(t, av[2], atoi(av[3]), atoi(av[4]));
-}
-
-int j_inputbox(const char *t, int ac, const char *const *av)
-{
-       int ret = dialog_inputbox(t, av[2], atoi(av[3]), atoi(av[4]),
-                                 ac == 6 ? av[5] : (char *)NULL);
-       if (ret == 0)
-               fprintf(stderr, dialog_input_result);
-       return ret;
-}
-
-int j_msgbox(const char *t, int ac, const char *const *av)
-{
-       return dialog_msgbox(t, av[2], atoi(av[3]), atoi(av[4]), 1);
-}
-
-int j_infobox(const char *t, int ac, const char *const *av)
-{
-       return dialog_msgbox(t, av[2], atoi(av[3]), atoi(av[4]), 0);
-}
index bf8052f4fd4ab73c80cfd2040ed69d4562e456e0..0d83159d90127a1dad38be99edff1a0973353a33 100644 (file)
@@ -63,19 +63,19 @@ static int menu_width, item_x;
 /*
  * Print menu item
  */
-static void do_print_item(WINDOW * win, const char *item, int choice,
+static void do_print_item(WINDOW * win, const char *item, int line_y,
                           int selected, int hotkey)
 {
        int j;
        char *menu_item = malloc(menu_width + 1);
 
        strncpy(menu_item, item, menu_width - item_x);
-       menu_item[menu_width] = 0;
+       menu_item[menu_width - item_x] = '\0';
        j = first_alpha(menu_item, "YyNnMmHh");
 
        /* Clear 'residue' of last item */
-       wattrset(win, menubox_attr);
-       wmove(win, choice, 0);
+       wattrset(win, dlg.menubox.atr);
+       wmove(win, line_y, 0);
 #if OLD_NCURSES
        {
                int i;
@@ -85,23 +85,24 @@ static void do_print_item(WINDOW * win, const char *item, int choice,
 #else
        wclrtoeol(win);
 #endif
-       wattrset(win, selected ? item_selected_attr : item_attr);
-       mvwaddstr(win, choice, item_x, menu_item);
+       wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
+       mvwaddstr(win, line_y, item_x, menu_item);
        if (hotkey) {
-               wattrset(win, selected ? tag_key_selected_attr : tag_key_attr);
-               mvwaddch(win, choice, item_x + j, menu_item[j]);
+               wattrset(win, selected ? dlg.tag_key_selected.atr
+                        : dlg.tag_key.atr);
+               mvwaddch(win, line_y, item_x + j, menu_item[j]);
        }
        if (selected) {
-               wmove(win, choice, item_x + 1);
+               wmove(win, line_y, item_x + 1);
        }
        free(menu_item);
        wrefresh(win);
 }
 
-#define print_item(index, choice, selected) \
-do {\
-       int hotkey = (items[(index) * 2][0] != ':'); \
-       do_print_item(menu, items[(index) * 2 + 1], choice, selected, hotkey); \
+#define print_item(index, choice, selected)                            \
+do {                                                                   \
+       item_set(index);                                                \
+       do_print_item(menu, item_str(), choice, selected, !item_is_tag(':')); \
 } while (0)
 
 /*
@@ -117,11 +118,11 @@ static void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x,
        wmove(win, y, x);
 
        if (scroll > 0) {
-               wattrset(win, uarrow_attr);
+               wattrset(win, dlg.uarrow.atr);
                waddch(win, ACS_UARROW);
                waddstr(win, "(-)");
        } else {
-               wattrset(win, menubox_attr);
+               wattrset(win, dlg.menubox.atr);
                waddch(win, ACS_HLINE);
                waddch(win, ACS_HLINE);
                waddch(win, ACS_HLINE);
@@ -133,11 +134,11 @@ static void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x,
        wrefresh(win);
 
        if ((height < item_no) && (scroll + height < item_no)) {
-               wattrset(win, darrow_attr);
+               wattrset(win, dlg.darrow.atr);
                waddch(win, ACS_DARROW);
                waddstr(win, "(+)");
        } else {
-               wattrset(win, menubox_border_attr);
+               wattrset(win, dlg.menubox_border.atr);
                waddch(win, ACS_HLINE);
                waddch(win, ACS_HLINE);
                waddch(win, ACS_HLINE);
@@ -178,17 +179,26 @@ static void do_scroll(WINDOW *win, int *scroll, int n)
 /*
  * Display a menu for choosing among a number of options
  */
-int dialog_menu(const char *title, const char *prompt, int height, int width,
-                int menu_height, const char *current, int item_no,
-                const char *const *items)
+int dialog_menu(const char *title, const char *prompt,
+                const void *selected, int *s_scroll)
 {
        int i, j, x, y, box_x, box_y;
+       int height, width, menu_height;
        int key = 0, button = 0, scroll = 0, choice = 0;
        int first_item =  0, max_choice;
        WINDOW *dialog, *menu;
-       FILE *f;
 
-       max_choice = MIN(menu_height, item_no);
+do_resize:
+       height = getmaxy(stdscr);
+       width = getmaxx(stdscr);
+       if (height < 15 || width < 65)
+               return -ERRDISPLAYTOOSMALL;
+
+       height -= 4;
+       width  -= 5;
+       menu_height = height - 10;
+
+       max_choice = MIN(menu_height, item_count());
 
        /* center dialog box on screen */
        x = (COLS - width) / 2;
@@ -199,18 +209,19 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
        dialog = newwin(height, width, y, x);
        keypad(dialog, TRUE);
 
-       draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
-       wattrset(dialog, border_attr);
+       draw_box(dialog, 0, 0, height, width,
+                dlg.dialog.atr, dlg.border.atr);
+       wattrset(dialog, dlg.border.atr);
        mvwaddch(dialog, height - 3, 0, ACS_LTEE);
        for (i = 0; i < width - 2; i++)
                waddch(dialog, ACS_HLINE);
-       wattrset(dialog, dialog_attr);
-       wbkgdset(dialog, dialog_attr & A_COLOR);
+       wattrset(dialog, dlg.dialog.atr);
+       wbkgdset(dialog, dlg.dialog.atr & A_COLOR);
        waddch(dialog, ACS_RTEE);
 
        print_title(dialog, title, width);
 
-       wattrset(dialog, dialog_attr);
+       wattrset(dialog, dlg.dialog.atr);
        print_autowrap(dialog, prompt, width - 2, 1, 3);
 
        menu_width = width - 6;
@@ -224,33 +235,29 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
 
        /* draw a box around the menu items */
        draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2,
-                menubox_border_attr, menubox_attr);
+                dlg.menubox_border.atr, dlg.menubox.atr);
 
-       item_x = (menu_width - 70) / 2;
+       if (menu_width >= 80)
+               item_x = (menu_width - 70) / 2;
+       else
+               item_x = 4;
 
        /* Set choice to default item */
-       for (i = 0; i < item_no; i++)
-               if (strcmp(current, items[i * 2]) == 0)
-                       choice = i;
-
-       /* get the scroll info from the temp file */
-       if ((f = fopen("lxdialog.scrltmp", "r")) != NULL) {
-               if ((fscanf(f, "%d\n", &scroll) == 1) && (scroll <= choice) &&
-                   (scroll + max_choice > choice) && (scroll >= 0) &&
-                   (scroll + max_choice <= item_no)) {
-                       first_item = scroll;
-                       choice = choice - scroll;
-                       fclose(f);
-               } else {
-                       scroll = 0;
-                       remove("lxdialog.scrltmp");
-                       fclose(f);
-                       f = NULL;
-               }
+       item_foreach()
+               if (selected && (selected == item_data()))
+                       choice = item_n();
+       /* get the saved scroll info */
+       scroll = *s_scroll;
+       if ((scroll <= choice) && (scroll + max_choice > choice) &&
+          (scroll >= 0) && (scroll + max_choice <= item_count())) {
+               first_item = scroll;
+               choice = choice - scroll;
+       } else {
+               scroll = 0;
        }
-       if ((choice >= max_choice) || (f == NULL && choice >= max_choice / 2)) {
-               if (choice >= item_no - max_choice / 2)
-                       scroll = first_item = item_no - max_choice;
+       if ((choice >= max_choice)) {
+               if (choice >= item_count() - max_choice / 2)
+                       scroll = first_item = item_count() - max_choice;
                else
                        scroll = first_item = choice - max_choice / 2;
                choice = choice - scroll;
@@ -263,14 +270,14 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
 
        wnoutrefresh(menu);
 
-       print_arrows(dialog, item_no, scroll,
+       print_arrows(dialog, item_count(), scroll,
                     box_y, box_x + item_x + 1, menu_height);
 
        print_buttons(dialog, height, width, 0);
        wmove(menu, choice, item_x + 1);
        wrefresh(menu);
 
-       while (key != ESC) {
+       while (key != KEY_ESC) {
                key = wgetch(menu);
 
                if (key < 256 && isalpha(key))
@@ -280,14 +287,16 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
                        i = max_choice;
                else {
                        for (i = choice + 1; i < max_choice; i++) {
-                               j = first_alpha(items[(scroll + i) * 2 + 1], "YyNnMmHh");
-                               if (key == tolower(items[(scroll + i) * 2 + 1][j]))
+                               item_set(scroll + i);
+                               j = first_alpha(item_str(), "YyNnMmHh");
+                               if (key == tolower(item_str()[j]))
                                        break;
                        }
                        if (i == max_choice)
                                for (i = 0; i < max_choice; i++) {
-                                       j = first_alpha(items [(scroll + i) * 2 + 1], "YyNnMmHh");
-                                       if (key == tolower(items[(scroll + i) * 2 + 1][j]))
+                                       item_set(scroll + i);
+                                       j = first_alpha(item_str(), "YyNnMmHh");
+                                       if (key == tolower(item_str()[j]))
                                                break;
                                }
                }
@@ -312,7 +321,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
                                print_item(scroll+choice, choice, FALSE);
 
                                if ((choice > max_choice - 3) &&
-                                   (scroll + max_choice < item_no)) {
+                                   (scroll + max_choice < item_count())) {
                                        /* Scroll menu up */
                                        do_scroll(menu, &scroll, 1);
 
@@ -335,7 +344,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
 
                        } else if (key == KEY_NPAGE) {
                                for (i = 0; (i < max_choice); i++) {
-                                       if (scroll + max_choice < item_no) {
+                                       if (scroll + max_choice < item_count()) {
                                                do_scroll(menu, &scroll, 1);
                                                print_item(scroll+max_choice-1,
                                                           max_choice - 1, FALSE);
@@ -349,7 +358,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
 
                        print_item(scroll + choice, choice, TRUE);
 
-                       print_arrows(dialog, item_no, scroll,
+                       print_arrows(dialog, item_count(), scroll,
                                     box_y, box_x + item_x + 1, menu_height);
 
                        wnoutrefresh(dialog);
@@ -375,12 +384,11 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
                case 'm':
                case '/':
                        /* save scroll info */
-                       if ((f = fopen("lxdialog.scrltmp", "w")) != NULL) {
-                               fprintf(f, "%d\n", scroll);
-                               fclose(f);
-                       }
+                       *s_scroll = scroll;
+                       delwin(menu);
                        delwin(dialog);
-                       fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);
+                       item_set(scroll + choice);
+                       item_set_selected(1);
                        switch (key) {
                        case 's':
                                return 3;
@@ -400,27 +408,27 @@ int dialog_menu(const char *title, const char *prompt, int height, int width,
                case '?':
                        button = 2;
                case '\n':
+                       *s_scroll = scroll;
+                       delwin(menu);
                        delwin(dialog);
-                       if (button == 2)
-                               fprintf(stderr, "%s \"%s\"\n",
-                                       items[(scroll + choice) * 2],
-                                       items[(scroll + choice) * 2 + 1] +
-                                       first_alpha(items [(scroll + choice) * 2 + 1], ""));
-                       else
-                               fprintf(stderr, "%s\n",
-                                       items[(scroll + choice) * 2]);
-
-                       remove("lxdialog.scrltmp");
+                       item_set(scroll + choice);
+                       item_set_selected(1);
                        return button;
                case 'e':
                case 'x':
-                       key = ESC;
-               case ESC:
+                       key = KEY_ESC;
+                       break;
+               case KEY_ESC:
+                       key = on_key_esc(menu);
                        break;
+               case KEY_RESIZE:
+                       on_key_resize();
+                       delwin(menu);
+                       delwin(dialog);
+                       goto do_resize;
                }
        }
-
+       delwin(menu);
        delwin(dialog);
-       remove("lxdialog.scrltmp");
-       return -1;              /* ESC pressed */
+       return key;             /* ESC pressed */
 }
diff --git a/scripts/kconfig/lxdialog/msgbox.c b/scripts/kconfig/lxdialog/msgbox.c
deleted file mode 100644 (file)
index 7323f54..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- *  msgbox.c -- implements the message box and info box
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.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.
- */
-
-#include "dialog.h"
-
-/*
- * Display a message box. Program will pause and display an "OK" button
- * if the parameter 'pause' is non-zero.
- */
-int dialog_msgbox(const char *title, const char *prompt, int height, int width,
-                  int pause)
-{
-       int i, x, y, key = 0;
-       WINDOW *dialog;
-
-       /* center dialog box on screen */
-       x = (COLS - width) / 2;
-       y = (LINES - height) / 2;
-
-       draw_shadow(stdscr, y, x, height, width);
-
-       dialog = newwin(height, width, y, x);
-       keypad(dialog, TRUE);
-
-       draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
-
-       print_title(dialog, title, width);
-
-       wattrset(dialog, dialog_attr);
-       print_autowrap(dialog, prompt, width - 2, 1, 2);
-
-       if (pause) {
-               wattrset(dialog, border_attr);
-               mvwaddch(dialog, height - 3, 0, ACS_LTEE);
-               for (i = 0; i < width - 2; i++)
-                       waddch(dialog, ACS_HLINE);
-               wattrset(dialog, dialog_attr);
-               waddch(dialog, ACS_RTEE);
-
-               print_button(dialog, "  Ok  ", height - 2, width / 2 - 4, TRUE);
-
-               wrefresh(dialog);
-               while (key != ESC && key != '\n' && key != ' ' &&
-                      key != 'O' && key != 'o' && key != 'X' && key != 'x')
-                       key = wgetch(dialog);
-       } else {
-               key = '\n';
-               wrefresh(dialog);
-       }
-
-       delwin(dialog);
-       return key == ESC ? -1 : 0;
-}
index 77848bb8e07f8795fbffeebee7980a0ee1adc269..fabfc1ad789d674f5f91637cba70cbfc335431d0 100644 (file)
@@ -25,56 +25,62 @@ static void back_lines(int n);
 static void print_page(WINDOW * win, int height, int width);
 static void print_line(WINDOW * win, int row, int width);
 static char *get_line(void);
-static void print_position(WINDOW * win, int height, int width);
+static void print_position(WINDOW * win);
+
+static int hscroll;
+static int begin_reached, end_reached, page_length;
+static const char *buf;
+static const char *page;
+
+/*
+ * refresh window content
+ */
+static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
+                                                         int cur_y, int cur_x)
+{
+       print_page(box, boxh, boxw);
+       print_position(dialog);
+       wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
+       wrefresh(dialog);
+}
 
-static int hscroll, fd, file_size, bytes_read;
-static int begin_reached = 1, end_reached, page_length;
-static char *buf, *page;
 
 /*
  * Display text from a file in a dialog box.
  */
-int dialog_textbox(const char *title, const char *file, int height, int width)
+int dialog_textbox(const char *title, const char *tbuf,
+                  int initial_height, int initial_width)
 {
-       int i, x, y, cur_x, cur_y, fpos, key = 0;
+       int i, x, y, cur_x, cur_y, key = 0;
+       int height, width, boxh, boxw;
        int passed_end;
-       char search_term[MAX_LEN + 1];
-       WINDOW *dialog, *text;
-
-       search_term[0] = '\0';  /* no search term entered yet */
+       WINDOW *dialog, *box;
 
-       /* Open input file for reading */
-       if ((fd = open(file, O_RDONLY)) == -1) {
-               endwin();
-               fprintf(stderr, "\nCan't open input file in dialog_textbox().\n");
-               exit(-1);
-       }
-       /* Get file size. Actually, 'file_size' is the real file size - 1,
-          since it's only the last byte offset from the beginning */
-       if ((file_size = lseek(fd, 0, SEEK_END)) == -1) {
-               endwin();
-               fprintf(stderr, "\nError getting file size in dialog_textbox().\n");
-               exit(-1);
-       }
-       /* Restore file pointer to beginning of file after getting file size */
-       if (lseek(fd, 0, SEEK_SET) == -1) {
-               endwin();
-               fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
-               exit(-1);
-       }
-       /* Allocate space for read buffer */
-       if ((buf = malloc(BUF_SIZE + 1)) == NULL) {
-               endwin();
-               fprintf(stderr, "\nCan't allocate memory in dialog_textbox().\n");
-               exit(-1);
-       }
-       if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
-               endwin();
-               fprintf(stderr, "\nError reading file in dialog_textbox().\n");
-               exit(-1);
-       }
-       buf[bytes_read] = '\0'; /* mark end of valid data */
-       page = buf;             /* page is pointer to start of page to be displayed */
+       begin_reached = 1;
+       end_reached = 0;
+       page_length = 0;
+       hscroll = 0;
+       buf = tbuf;
+       page = buf;     /* page is pointer to start of page to be displayed */
+
+do_resize:
+       getmaxyx(stdscr, height, width);
+       if (height < 8 || width < 8)
+               return -ERRDISPLAYTOOSMALL;
+       if (initial_height != 0)
+               height = initial_height;
+       else
+               if (height > 4)
+                       height -= 4;
+               else
+                       height = 0;
+       if (initial_width != 0)
+               width = initial_width;
+       else
+               if (width > 5)
+                       width -= 5;
+               else
+                       width = 0;
 
        /* center dialog box on screen */
        x = (COLS - width) / 2;
@@ -85,22 +91,25 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
        dialog = newwin(height, width, y, x);
        keypad(dialog, TRUE);
 
-       /* Create window for text region, used for scrolling text */
-       text = subwin(dialog, height - 4, width - 2, y + 1, x + 1);
-       wattrset(text, dialog_attr);
-       wbkgdset(text, dialog_attr & A_COLOR);
+       /* Create window for box region, used for scrolling text */
+       boxh = height - 4;
+       boxw = width - 2;
+       box = subwin(dialog, boxh, boxw, y + 1, x + 1);
+       wattrset(box, dlg.dialog.atr);
+       wbkgdset(box, dlg.dialog.atr & A_COLOR);
 
-       keypad(text, TRUE);
+       keypad(box, TRUE);
 
        /* register the new window, along with its borders */
-       draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+       draw_box(dialog, 0, 0, height, width,
+                dlg.dialog.atr, dlg.border.atr);
 
-       wattrset(dialog, border_attr);
+       wattrset(dialog, dlg.border.atr);
        mvwaddch(dialog, height - 3, 0, ACS_LTEE);
        for (i = 0; i < width - 2; i++)
                waddch(dialog, ACS_HLINE);
-       wattrset(dialog, dialog_attr);
-       wbkgdset(dialog, dialog_attr & A_COLOR);
+       wattrset(dialog, dlg.dialog.atr);
+       wbkgdset(dialog, dlg.dialog.atr & A_COLOR);
        waddch(dialog, ACS_RTEE);
 
        print_title(dialog, title, width);
@@ -110,85 +119,37 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
        getyx(dialog, cur_y, cur_x);    /* Save cursor position */
 
        /* Print first page of text */
-       attr_clear(text, height - 4, width - 2, dialog_attr);
-       print_page(text, height - 4, width - 2);
-       print_position(dialog, height, width);
-       wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
-       wrefresh(dialog);
+       attr_clear(box, boxh, boxw, dlg.dialog.atr);
+       refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
 
-       while ((key != ESC) && (key != '\n')) {
+       while ((key != KEY_ESC) && (key != '\n')) {
                key = wgetch(dialog);
                switch (key) {
                case 'E':       /* Exit */
                case 'e':
                case 'X':
                case 'x':
+                       delwin(box);
                        delwin(dialog);
-                       free(buf);
-                       close(fd);
                        return 0;
                case 'g':       /* First page */
                case KEY_HOME:
                        if (!begin_reached) {
                                begin_reached = 1;
-                               /* First page not in buffer? */
-                               if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
-                                       endwin();
-                                       fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
-                                       exit(-1);
-                               }
-                               if (fpos > bytes_read) {        /* Yes, we have to read it in */
-                                       if (lseek(fd, 0, SEEK_SET) == -1) {
-                                               endwin();
-                                               fprintf(stderr, "\nError moving file pointer in "
-                                                               "dialog_textbox().\n");
-                                               exit(-1);
-                                       }
-                                       if ((bytes_read =
-                                            read(fd, buf, BUF_SIZE)) == -1) {
-                                               endwin();
-                                               fprintf(stderr, "\nError reading file in dialog_textbox().\n");
-                                               exit(-1);
-                                       }
-                                       buf[bytes_read] = '\0';
-                               }
                                page = buf;
-                               print_page(text, height - 4, width - 2);
-                               print_position(dialog, height, width);
-                               wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
-                               wrefresh(dialog);
+                               refresh_text_box(dialog, box, boxh, boxw,
+                                                cur_y, cur_x);
                        }
                        break;
                case 'G':       /* Last page */
                case KEY_END:
 
                        end_reached = 1;
-                       /* Last page not in buffer? */
-                       if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
-                               endwin();
-                               fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
-                               exit(-1);
-                       }
-                       if (fpos < file_size) { /* Yes, we have to read it in */
-                               if (lseek(fd, -BUF_SIZE, SEEK_END) == -1) {
-                                       endwin();
-                                       fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
-                                       exit(-1);
-                               }
-                               if ((bytes_read =
-                                    read(fd, buf, BUF_SIZE)) == -1) {
-                                       endwin();
-                                       fprintf(stderr, "\nError reading file in dialog_textbox().\n");
-                                       exit(-1);
-                               }
-                               buf[bytes_read] = '\0';
-                       }
-                       page = buf + bytes_read;
-                       back_lines(height - 4);
-                       print_page(text, height - 4, width - 2);
-                       print_position(dialog, height, width);
-                       wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
-                       wrefresh(dialog);
+                       /* point to last char in buf */
+                       page = buf + strlen(buf);
+                       back_lines(boxh);
+                       refresh_text_box(dialog, box, boxh, boxw,
+                                        cur_y, cur_x);
                        break;
                case 'K':       /* Previous line */
                case 'k':
@@ -196,21 +157,23 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
                        if (!begin_reached) {
                                back_lines(page_length + 1);
 
-                               /* We don't call print_page() here but use scrolling to ensure
-                                  faster screen update. However, 'end_reached' and
-                                  'page_length' should still be updated, and 'page' should
-                                  point to start of next page. This is done by calling
-                                  get_line() in the following 'for' loop. */
-                               scrollok(text, TRUE);
-                               wscrl(text, -1);        /* Scroll text region down one line */
-                               scrollok(text, FALSE);
+                               /* We don't call print_page() here but use
+                                * scrolling to ensure faster screen update.
+                                * However, 'end_reached' and 'page_length'
+                                * should still be updated, and 'page' should
+                                * point to start of next page. This is done
+                                * by calling get_line() in the following
+                                * 'for' loop. */
+                               scrollok(box, TRUE);
+                               wscrl(box, -1); /* Scroll box region down one line */
+                               scrollok(box, FALSE);
                                page_length = 0;
                                passed_end = 0;
-                               for (i = 0; i < height - 4; i++) {
+                               for (i = 0; i < boxh; i++) {
                                        if (!i) {
                                                /* print first line of page */
-                                               print_line(text, 0, width - 2);
-                                               wnoutrefresh(text);
+                                               print_line(box, 0, boxw);
+                                               wnoutrefresh(box);
                                        } else
                                                /* Called to update 'end_reached' and 'page' */
                                                get_line();
@@ -220,7 +183,7 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
                                                passed_end = 1;
                                }
 
-                               print_position(dialog, height, width);
+                               print_position(dialog);
                                wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
                                wrefresh(dialog);
                        }
@@ -230,23 +193,21 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
                case KEY_PPAGE:
                        if (begin_reached)
                                break;
-                       back_lines(page_length + height - 4);
-                       print_page(text, height - 4, width - 2);
-                       print_position(dialog, height, width);
-                       wmove(dialog, cur_y, cur_x);
-                       wrefresh(dialog);
+                       back_lines(page_length + boxh);
+                       refresh_text_box(dialog, box, boxh, boxw,
+                                        cur_y, cur_x);
                        break;
                case 'J':       /* Next line */
                case 'j':
                case KEY_DOWN:
                        if (!end_reached) {
                                begin_reached = 0;
-                               scrollok(text, TRUE);
-                               scroll(text);   /* Scroll text region up one line */
-                               scrollok(text, FALSE);
-                               print_line(text, height - 5, width - 2);
-                               wnoutrefresh(text);
-                               print_position(dialog, height, width);
+                               scrollok(box, TRUE);
+                               scroll(box);    /* Scroll box region up one line */
+                               scrollok(box, FALSE);
+                               print_line(box, boxh - 1, boxw);
+                               wnoutrefresh(box);
+                               print_position(dialog);
                                wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
                                wrefresh(dialog);
                        }
@@ -257,10 +218,8 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
                                break;
 
                        begin_reached = 0;
-                       print_page(text, height - 4, width - 2);
-                       print_position(dialog, height, width);
-                       wmove(dialog, cur_y, cur_x);
-                       wrefresh(dialog);
+                       refresh_text_box(dialog, box, boxh, boxw,
+                                        cur_y, cur_x);
                        break;
                case '0':       /* Beginning of line */
                case 'H':       /* Scroll left */
@@ -275,9 +234,8 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
                                hscroll--;
                        /* Reprint current page to scroll horizontally */
                        back_lines(page_length);
-                       print_page(text, height - 4, width - 2);
-                       wmove(dialog, cur_y, cur_x);
-                       wrefresh(dialog);
+                       refresh_text_box(dialog, box, boxh, boxw,
+                                        cur_y, cur_x);
                        break;
                case 'L':       /* Scroll right */
                case 'l':
@@ -287,131 +245,56 @@ int dialog_textbox(const char *title, const char *file, int height, int width)
                        hscroll++;
                        /* Reprint current page to scroll horizontally */
                        back_lines(page_length);
-                       print_page(text, height - 4, width - 2);
-                       wmove(dialog, cur_y, cur_x);
-                       wrefresh(dialog);
+                       refresh_text_box(dialog, box, boxh, boxw,
+                                        cur_y, cur_x);
                        break;
-               case ESC:
+               case KEY_ESC:
+                       key = on_key_esc(dialog);
                        break;
+               case KEY_RESIZE:
+                       back_lines(height);
+                       delwin(box);
+                       delwin(dialog);
+                       on_key_resize();
+                       goto do_resize;
                }
        }
-
+       delwin(box);
        delwin(dialog);
-       free(buf);
-       close(fd);
-       return -1;              /* ESC pressed */
+       return key;             /* ESC pressed */
 }
 
 /*
- * Go back 'n' lines in text file. Called by dialog_textbox().
+ * Go back 'n' lines in text. Called by dialog_textbox().
  * 'page' will be updated to point to the desired line in 'buf'.
  */
 static void back_lines(int n)
 {
-       int i, fpos;
+       int i;
 
        begin_reached = 0;
-       /* We have to distinguish between end_reached and !end_reached
-          since at end of file, the line is not ended by a '\n'.
-          The code inside 'if' basically does a '--page' to move one
-          character backward so as to skip '\n' of the previous line */
-       if (!end_reached) {
-               /* Either beginning of buffer or beginning of file reached? */
-               if (page == buf) {
-                       if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
-                               endwin();
-                               fprintf(stderr, "\nError moving file pointer in "
-                                               "back_lines().\n");
-                               exit(-1);
-                       }
-                       if (fpos > bytes_read) {        /* Not beginning of file yet */
-                               /* We've reached beginning of buffer, but not beginning of
-                                  file yet, so read previous part of file into buffer.
-                                  Note that we only move backward for BUF_SIZE/2 bytes,
-                                  but not BUF_SIZE bytes to avoid re-reading again in
-                                  print_page() later */
-                               /* Really possible to move backward BUF_SIZE/2 bytes? */
-                               if (fpos < BUF_SIZE / 2 + bytes_read) {
-                                       /* No, move less then */
-                                       if (lseek(fd, 0, SEEK_SET) == -1) {
-                                               endwin();
-                                               fprintf(stderr, "\nError moving file pointer in "
-                                                               "back_lines().\n");
-                                               exit(-1);
-                                       }
-                                       page = buf + fpos - bytes_read;
-                               } else {        /* Move backward BUF_SIZE/2 bytes */
-                                       if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) == -1) {
-                                               endwin();
-                                               fprintf(stderr, "\nError moving file pointer "
-                                                               "in back_lines().\n");
-                                               exit(-1);
-                                       }
-                                       page = buf + BUF_SIZE / 2;
-                               }
-                               if ((bytes_read =
-                                    read(fd, buf, BUF_SIZE)) == -1) {
-                                       endwin();
-                                       fprintf(stderr, "\nError reading file in back_lines().\n");
-                                       exit(-1);
-                               }
-                               buf[bytes_read] = '\0';
-                       } else {        /* Beginning of file reached */
-                               begin_reached = 1;
-                               return;
+       /* Go back 'n' lines */
+       for (i = 0; i < n; i++) {
+               if (*page == '\0') {
+                       if (end_reached) {
+                               end_reached = 0;
+                               continue;
                        }
                }
-               if (*(--page) != '\n') {        /* '--page' here */
-                       /* Something's wrong... */
-                       endwin();
-                       fprintf(stderr, "\nInternal error in back_lines().\n");
-                       exit(-1);
+               if (page == buf) {
+                       begin_reached = 1;
+                       return;
                }
-       }
-       /* Go back 'n' lines */
-       for (i = 0; i < n; i++)
+               page--;
                do {
                        if (page == buf) {
-                               if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
-                                       endwin();
-                                       fprintf(stderr, "\nError moving file pointer in back_lines().\n");
-                                       exit(-1);
-                               }
-                               if (fpos > bytes_read) {
-                                       /* Really possible to move backward BUF_SIZE/2 bytes? */
-                                       if (fpos < BUF_SIZE / 2 + bytes_read) {
-                                               /* No, move less then */
-                                               if (lseek(fd, 0, SEEK_SET) == -1) {
-                                                       endwin();
-                                                       fprintf(stderr, "\nError moving file pointer "
-                                                                       "in back_lines().\n");
-                                                       exit(-1);
-                                               }
-                                               page = buf + fpos - bytes_read;
-                                       } else {        /* Move backward BUF_SIZE/2 bytes */
-                                               if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) == -1) {
-                                                       endwin();
-                                                       fprintf(stderr, "\nError moving file pointer"
-                                                                       " in back_lines().\n");
-                                                       exit(-1);
-                                               }
-                                               page = buf + BUF_SIZE / 2;
-                                       }
-                                       if ((bytes_read =
-                                            read(fd, buf, BUF_SIZE)) == -1) {
-                                               endwin();
-                                               fprintf(stderr, "\nError reading file in "
-                                                               "back_lines().\n");
-                                               exit(-1);
-                                       }
-                                       buf[bytes_read] = '\0';
-                               } else {        /* Beginning of file reached */
-                                       begin_reached = 1;
-                                       return;
-                               }
+                               begin_reached = 1;
+                               return;
                        }
-               } while (*(--page) != '\n');
-       page++;
+                       page--;
+               } while (*page != '\n');
+               page++;
+       }
 }
 
 /*
@@ -466,33 +349,14 @@ static void print_line(WINDOW * win, int row, int width)
  */
 static char *get_line(void)
 {
-       int i = 0, fpos;
+       int i = 0;
        static char line[MAX_LEN + 1];
 
        end_reached = 0;
        while (*page != '\n') {
                if (*page == '\0') {
-                       /* Either end of file or end of buffer reached */
-                       if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
-                               endwin();
-                               fprintf(stderr, "\nError moving file pointer in "
-                                               "get_line().\n");
-                               exit(-1);
-                       }
-                       if (fpos < file_size) { /* Not end of file yet */
-                               /* We've reached end of buffer, but not end of file yet,
-                                  so read next part of file into buffer */
-                               if ((bytes_read =
-                                    read(fd, buf, BUF_SIZE)) == -1) {
-                                       endwin();
-                                       fprintf(stderr, "\nError reading file in get_line().\n");
-                                       exit(-1);
-                               }
-                               buf[bytes_read] = '\0';
-                               page = buf;
-                       } else {
-                               if (!end_reached)
-                                       end_reached = 1;
+                       if (!end_reached) {
+                               end_reached = 1;
                                break;
                        }
                } else if (i < MAX_LEN)
@@ -515,19 +379,13 @@ static char *get_line(void)
 /*
  * Print current position
  */
-static void print_position(WINDOW * win, int height, int width)
+static void print_position(WINDOW * win)
 {
-       int fpos, percent;
+       int percent;
 
-       if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
-               endwin();
-               fprintf(stderr, "\nError moving file pointer in print_position().\n");
-               exit(-1);
-       }
-       wattrset(win, position_indicator_attr);
-       wbkgdset(win, position_indicator_attr & A_COLOR);
-       percent = !file_size ?
-           100 : ((fpos - bytes_read + page - buf) * 100) / file_size;
-       wmove(win, height - 3, width - 9);
+       wattrset(win, dlg.position_indicator.atr);
+       wbkgdset(win, dlg.position_indicator.atr & A_COLOR);
+       percent = (page - buf) * 100 / strlen(buf);
+       wmove(win, getmaxy(win) - 3, getmaxx(win) - 9);
        wprintw(win, "(%3d%%)", percent);
 }
index f82cebb9ff06d718f758f24f5674a671c17a36e1..ebc781b493d7c8a86ca7d95bae7f943bbb5430a9 100644 (file)
 
 #include "dialog.h"
 
-/* use colors by default? */
-bool use_colors = 1;
+struct dialog_info dlg;
 
-const char *backtitle = NULL;
+static void set_mono_theme(void)
+{
+       dlg.screen.atr = A_NORMAL;
+       dlg.shadow.atr = A_NORMAL;
+       dlg.dialog.atr = A_NORMAL;
+       dlg.title.atr = A_BOLD;
+       dlg.border.atr = A_NORMAL;
+       dlg.button_active.atr = A_REVERSE;
+       dlg.button_inactive.atr = A_DIM;
+       dlg.button_key_active.atr = A_REVERSE;
+       dlg.button_key_inactive.atr = A_BOLD;
+       dlg.button_label_active.atr = A_REVERSE;
+       dlg.button_label_inactive.atr = A_NORMAL;
+       dlg.inputbox.atr = A_NORMAL;
+       dlg.inputbox_border.atr = A_NORMAL;
+       dlg.searchbox.atr = A_NORMAL;
+       dlg.searchbox_title.atr = A_BOLD;
+       dlg.searchbox_border.atr = A_NORMAL;
+       dlg.position_indicator.atr = A_BOLD;
+       dlg.menubox.atr = A_NORMAL;
+       dlg.menubox_border.atr = A_NORMAL;
+       dlg.item.atr = A_NORMAL;
+       dlg.item_selected.atr = A_REVERSE;
+       dlg.tag.atr = A_BOLD;
+       dlg.tag_selected.atr = A_REVERSE;
+       dlg.tag_key.atr = A_BOLD;
+       dlg.tag_key_selected.atr = A_REVERSE;
+       dlg.check.atr = A_BOLD;
+       dlg.check_selected.atr = A_REVERSE;
+       dlg.uarrow.atr = A_BOLD;
+       dlg.darrow.atr = A_BOLD;
+}
+
+#define DLG_COLOR(dialog, f, b, h) \
+do {                               \
+       dlg.dialog.fg = (f);       \
+       dlg.dialog.bg = (b);       \
+       dlg.dialog.hl = (h);       \
+} while (0)
+
+static void set_classic_theme(void)
+{
+       DLG_COLOR(screen,                COLOR_CYAN,   COLOR_BLUE,   true);
+       DLG_COLOR(shadow,                COLOR_BLACK,  COLOR_BLACK,  true);
+       DLG_COLOR(dialog,                COLOR_BLACK,  COLOR_WHITE,  false);
+       DLG_COLOR(title,                 COLOR_YELLOW, COLOR_WHITE,  true);
+       DLG_COLOR(border,                COLOR_WHITE,  COLOR_WHITE,  true);
+       DLG_COLOR(button_active,         COLOR_WHITE,  COLOR_BLUE,   true);
+       DLG_COLOR(button_inactive,       COLOR_BLACK,  COLOR_WHITE,  false);
+       DLG_COLOR(button_key_active,     COLOR_WHITE,  COLOR_BLUE,   true);
+       DLG_COLOR(button_key_inactive,   COLOR_RED,    COLOR_WHITE,  false);
+       DLG_COLOR(button_label_active,   COLOR_YELLOW, COLOR_BLUE,   true);
+       DLG_COLOR(button_label_inactive, COLOR_BLACK,  COLOR_WHITE,  true);
+       DLG_COLOR(inputbox,              COLOR_BLACK,  COLOR_WHITE,  false);
+       DLG_COLOR(inputbox_border,       COLOR_BLACK,  COLOR_WHITE,  false);
+       DLG_COLOR(searchbox,             COLOR_BLACK,  COLOR_WHITE,  false);
+       DLG_COLOR(searchbox_title,       COLOR_YELLOW, COLOR_WHITE,  true);
+       DLG_COLOR(searchbox_border,      COLOR_WHITE,  COLOR_WHITE,  true);
+       DLG_COLOR(position_indicator,    COLOR_YELLOW, COLOR_WHITE,  true);
+       DLG_COLOR(menubox,               COLOR_BLACK,  COLOR_WHITE,  false);
+       DLG_COLOR(menubox_border,        COLOR_WHITE,  COLOR_WHITE,  true);
+       DLG_COLOR(item,                  COLOR_BLACK,  COLOR_WHITE,  false);
+       DLG_COLOR(item_selected,         COLOR_WHITE,  COLOR_BLUE,   true);
+       DLG_COLOR(tag,                   COLOR_YELLOW, COLOR_WHITE,  true);
+       DLG_COLOR(tag_selected,          COLOR_YELLOW, COLOR_BLUE,   true);
+       DLG_COLOR(tag_key,               COLOR_YELLOW, COLOR_WHITE,  true);
+       DLG_COLOR(tag_key_selected,      COLOR_YELLOW, COLOR_BLUE,   true);
+       DLG_COLOR(check,                 COLOR_BLACK,  COLOR_WHITE,  false);
+       DLG_COLOR(check_selected,        COLOR_WHITE,  COLOR_BLUE,   true);
+       DLG_COLOR(uarrow,                COLOR_GREEN,  COLOR_WHITE,  true);
+       DLG_COLOR(darrow,                COLOR_GREEN,  COLOR_WHITE,  true);
+}
+
+static void set_blackbg_theme(void)
+{
+       DLG_COLOR(screen, COLOR_RED,   COLOR_BLACK, true);
+       DLG_COLOR(shadow, COLOR_BLACK, COLOR_BLACK, false);
+       DLG_COLOR(dialog, COLOR_WHITE, COLOR_BLACK, false);
+       DLG_COLOR(title,  COLOR_RED,   COLOR_BLACK, false);
+       DLG_COLOR(border, COLOR_BLACK, COLOR_BLACK, true);
+
+       DLG_COLOR(button_active,         COLOR_YELLOW, COLOR_RED,   false);
+       DLG_COLOR(button_inactive,       COLOR_YELLOW, COLOR_BLACK, false);
+       DLG_COLOR(button_key_active,     COLOR_YELLOW, COLOR_RED,   true);
+       DLG_COLOR(button_key_inactive,   COLOR_RED,    COLOR_BLACK, false);
+       DLG_COLOR(button_label_active,   COLOR_WHITE,  COLOR_RED,   false);
+       DLG_COLOR(button_label_inactive, COLOR_BLACK,  COLOR_BLACK, true);
+
+       DLG_COLOR(inputbox,         COLOR_YELLOW, COLOR_BLACK, false);
+       DLG_COLOR(inputbox_border,  COLOR_YELLOW, COLOR_BLACK, false);
+
+       DLG_COLOR(searchbox,        COLOR_YELLOW, COLOR_BLACK, false);
+       DLG_COLOR(searchbox_title,  COLOR_YELLOW, COLOR_BLACK, true);
+       DLG_COLOR(searchbox_border, COLOR_BLACK,  COLOR_BLACK, true);
+
+       DLG_COLOR(position_indicator, COLOR_RED, COLOR_BLACK,  false);
+
+       DLG_COLOR(menubox,          COLOR_YELLOW, COLOR_BLACK, false);
+       DLG_COLOR(menubox_border,   COLOR_BLACK,  COLOR_BLACK, true);
+
+       DLG_COLOR(item,             COLOR_WHITE, COLOR_BLACK, false);
+       DLG_COLOR(item_selected,    COLOR_WHITE, COLOR_RED,   false);
+
+       DLG_COLOR(tag,              COLOR_RED,    COLOR_BLACK, false);
+       DLG_COLOR(tag_selected,     COLOR_YELLOW, COLOR_RED,   true);
+       DLG_COLOR(tag_key,          COLOR_RED,    COLOR_BLACK, false);
+       DLG_COLOR(tag_key_selected, COLOR_YELLOW, COLOR_RED,   true);
+
+       DLG_COLOR(check,            COLOR_YELLOW, COLOR_BLACK, false);
+       DLG_COLOR(check_selected,   COLOR_YELLOW, COLOR_RED,   true);
+
+       DLG_COLOR(uarrow, COLOR_RED, COLOR_BLACK, false);
+       DLG_COLOR(darrow, COLOR_RED, COLOR_BLACK, false);
+}
+
+static void set_bluetitle_theme(void)
+{
+       set_classic_theme();
+       DLG_COLOR(title,               COLOR_BLUE,   COLOR_WHITE, true);
+       DLG_COLOR(button_key_active,   COLOR_YELLOW, COLOR_BLUE,  true);
+       DLG_COLOR(button_label_active, COLOR_WHITE,  COLOR_BLUE,  true);
+       DLG_COLOR(searchbox_title,     COLOR_BLUE,   COLOR_WHITE, true);
+       DLG_COLOR(position_indicator,  COLOR_BLUE,   COLOR_WHITE, true);
+       DLG_COLOR(tag,                 COLOR_BLUE,   COLOR_WHITE, true);
+       DLG_COLOR(tag_key,             COLOR_BLUE,   COLOR_WHITE, true);
+
+}
 
 /*
- * Attribute values, default is for mono display
+ * Select color theme
  */
-chtype attributes[] = {
-       A_NORMAL,               /* screen_attr */
-       A_NORMAL,               /* shadow_attr */
-       A_NORMAL,               /* dialog_attr */
-       A_BOLD,                 /* title_attr */
-       A_NORMAL,               /* border_attr */
-       A_REVERSE,              /* button_active_attr */
-       A_DIM,                  /* button_inactive_attr */
-       A_REVERSE,              /* button_key_active_attr */
-       A_BOLD,                 /* button_key_inactive_attr */
-       A_REVERSE,              /* button_label_active_attr */
-       A_NORMAL,               /* button_label_inactive_attr */
-       A_NORMAL,               /* inputbox_attr */
-       A_NORMAL,               /* inputbox_border_attr */
-       A_NORMAL,               /* searchbox_attr */
-       A_BOLD,                 /* searchbox_title_attr */
-       A_NORMAL,               /* searchbox_border_attr */
-       A_BOLD,                 /* position_indicator_attr */
-       A_NORMAL,               /* menubox_attr */
-       A_NORMAL,               /* menubox_border_attr */
-       A_NORMAL,               /* item_attr */
-       A_REVERSE,              /* item_selected_attr */
-       A_BOLD,                 /* tag_attr */
-       A_REVERSE,              /* tag_selected_attr */
-       A_BOLD,                 /* tag_key_attr */
-       A_REVERSE,              /* tag_key_selected_attr */
-       A_BOLD,                 /* check_attr */
-       A_REVERSE,              /* check_selected_attr */
-       A_BOLD,                 /* uarrow_attr */
-       A_BOLD                  /* darrow_attr */
-};
-
-#include "colors.h"
+static int set_theme(const char *theme)
+{
+       int use_color = 1;
+       if (!theme)
+               set_bluetitle_theme();
+       else if (strcmp(theme, "classic") == 0)
+               set_classic_theme();
+       else if (strcmp(theme, "bluetitle") == 0)
+               set_bluetitle_theme();
+       else if (strcmp(theme, "blackbg") == 0)
+               set_blackbg_theme();
+       else if (strcmp(theme, "mono") == 0)
+               use_color = 0;
+
+       return use_color;
+}
+
+static void init_one_color(struct dialog_color *color)
+{
+       static int pair = 0;
+
+       pair++;
+       init_pair(pair, color->fg, color->bg);
+       if (color->hl)
+               color->atr = A_BOLD | COLOR_PAIR(pair);
+       else
+               color->atr = COLOR_PAIR(pair);
+}
+
+static void init_dialog_colors(void)
+{
+       init_one_color(&dlg.screen);
+       init_one_color(&dlg.shadow);
+       init_one_color(&dlg.dialog);
+       init_one_color(&dlg.title);
+       init_one_color(&dlg.border);
+       init_one_color(&dlg.button_active);
+       init_one_color(&dlg.button_inactive);
+       init_one_color(&dlg.button_key_active);
+       init_one_color(&dlg.button_key_inactive);
+       init_one_color(&dlg.button_label_active);
+       init_one_color(&dlg.button_label_inactive);
+       init_one_color(&dlg.inputbox);
+       init_one_color(&dlg.inputbox_border);
+       init_one_color(&dlg.searchbox);
+       init_one_color(&dlg.searchbox_title);
+       init_one_color(&dlg.searchbox_border);
+       init_one_color(&dlg.position_indicator);
+       init_one_color(&dlg.menubox);
+       init_one_color(&dlg.menubox_border);
+       init_one_color(&dlg.item);
+       init_one_color(&dlg.item_selected);
+       init_one_color(&dlg.tag);
+       init_one_color(&dlg.tag_selected);
+       init_one_color(&dlg.tag_key);
+       init_one_color(&dlg.tag_key_selected);
+       init_one_color(&dlg.check);
+       init_one_color(&dlg.check_selected);
+       init_one_color(&dlg.uarrow);
+       init_one_color(&dlg.darrow);
+}
 
 /*
- * Table of color values
+ * Setup for color display
  */
-int color_table[][3] = {
-       {SCREEN_FG, SCREEN_BG, SCREEN_HL},
-       {SHADOW_FG, SHADOW_BG, SHADOW_HL},
-       {DIALOG_FG, DIALOG_BG, DIALOG_HL},
-       {TITLE_FG, TITLE_BG, TITLE_HL},
-       {BORDER_FG, BORDER_BG, BORDER_HL},
-       {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL},
-       {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL},
-       {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL},
-       {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG,
-        BUTTON_KEY_INACTIVE_HL},
-       {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG,
-        BUTTON_LABEL_ACTIVE_HL},
-       {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG,
-        BUTTON_LABEL_INACTIVE_HL},
-       {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL},
-       {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL},
-       {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL},
-       {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL},
-       {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL},
-       {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL},
-       {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL},
-       {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL},
-       {ITEM_FG, ITEM_BG, ITEM_HL},
-       {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL},
-       {TAG_FG, TAG_BG, TAG_HL},
-       {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL},
-       {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL},
-       {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL},
-       {CHECK_FG, CHECK_BG, CHECK_HL},
-       {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL},
-       {UARROW_FG, UARROW_BG, UARROW_HL},
-       {DARROW_FG, DARROW_BG, DARROW_HL},
-};                             /* color_table */
+static void color_setup(const char *theme)
+{
+       if (set_theme(theme)) {
+               if (has_colors()) {     /* Terminal supports color? */
+                       start_color();
+                       init_dialog_colors();
+               }
+       }
+       else
+       {
+               set_mono_theme();
+       }
+}
 
 /*
  * Set window to attribute 'attr'
@@ -119,13 +251,13 @@ void attr_clear(WINDOW * win, int height, int width, chtype attr)
 
 void dialog_clear(void)
 {
-       attr_clear(stdscr, LINES, COLS, screen_attr);
+       attr_clear(stdscr, LINES, COLS, dlg.screen.atr);
        /* Display background title if it exists ... - SLH */
-       if (backtitle != NULL) {
+       if (dlg.backtitle != NULL) {
                int i;
 
-               wattrset(stdscr, screen_attr);
-               mvwaddstr(stdscr, 0, 1, (char *)backtitle);
+               wattrset(stdscr, dlg.screen.atr);
+               mvwaddstr(stdscr, 0, 1, (char *)dlg.backtitle);
                wmove(stdscr, 1, 1);
                for (i = 1; i < COLS - 1; i++)
                        waddch(stdscr, ACS_HLINE);
@@ -136,39 +268,21 @@ void dialog_clear(void)
 /*
  * Do some initialization for dialog
  */
-void init_dialog(void)
+void init_dialog(const char *backtitle)
+{
+       dlg.backtitle = backtitle;
+       color_setup(getenv("MENUCONFIG_COLOR"));
+}
+
+void reset_dialog(void)
 {
        initscr();              /* Init curses */
        keypad(stdscr, TRUE);
        cbreak();
        noecho();
-
-       if (use_colors)         /* Set up colors */
-               color_setup();
-
        dialog_clear();
 }
 
-/*
- * Setup for color display
- */
-void color_setup(void)
-{
-       int i;
-
-       if (has_colors()) {     /* Terminal supports color? */
-               start_color();
-
-               /* Initialize color pairs */
-               for (i = 0; i < ATTRIBUTE_COUNT; i++)
-                       init_pair(i + 1, color_table[i][0], color_table[i][1]);
-
-               /* Setup color attributes */
-               for (i = 0; i < ATTRIBUTE_COUNT; i++)
-                       attributes[i] = C_ATTR(color_table[i][2], i + 1);
-       }
-}
-
 /*
  * End using dialog functions.
  */
@@ -184,7 +298,7 @@ void print_title(WINDOW *dialog, const char *title, int width)
 {
        if (title) {
                int tlen = MIN(width - 2, strlen(title));
-               wattrset(dialog, title_attr);
+               wattrset(dialog, dlg.title.atr);
                mvwaddch(dialog, 0, (width - tlen) / 2 - 1, ' ');
                mvwaddnstr(dialog, 0, (width - tlen)/2, title, tlen);
                waddch(dialog, ' ');
@@ -264,21 +378,23 @@ void print_button(WINDOW * win, const char *label, int y, int x, int selected)
        int i, temp;
 
        wmove(win, y, x);
-       wattrset(win, selected ? button_active_attr : button_inactive_attr);
+       wattrset(win, selected ? dlg.button_active.atr
+                : dlg.button_inactive.atr);
        waddstr(win, "<");
        temp = strspn(label, " ");
        label += temp;
-       wattrset(win, selected ? button_label_active_attr
-                : button_label_inactive_attr);
+       wattrset(win, selected ? dlg.button_label_active.atr
+                : dlg.button_label_inactive.atr);
        for (i = 0; i < temp; i++)
                waddch(win, ' ');
-       wattrset(win, selected ? button_key_active_attr
-                : button_key_inactive_attr);
+       wattrset(win, selected ? dlg.button_key_active.atr
+                : dlg.button_key_inactive.atr);
        waddch(win, label[0]);
-       wattrset(win, selected ? button_label_active_attr
-                : button_label_inactive_attr);
+       wattrset(win, selected ? dlg.button_label_active.atr
+                : dlg.button_label_inactive.atr);
        waddstr(win, (char *)label + 1);
-       wattrset(win, selected ? button_active_attr : button_inactive_attr);
+       wattrset(win, selected ? dlg.button_active.atr
+                : dlg.button_inactive.atr);
        waddstr(win, ">");
        wmove(win, y, x + temp + 1);
 }
@@ -326,7 +442,7 @@ void draw_shadow(WINDOW * win, int y, int x, int height, int width)
        int i;
 
        if (has_colors()) {     /* Whether terminal supports color? */
-               wattrset(win, shadow_attr);
+               wattrset(win, dlg.shadow.atr);
                wmove(win, y + height, x + 2);
                for (i = 0; i < width; i++)
                        waddch(win, winch(win) & A_CHARTEXT);
@@ -360,3 +476,167 @@ int first_alpha(const char *string, const char *exempt)
 
        return 0;
 }
+
+/*
+ * ncurses uses ESC to detect escaped char sequences. This resutl in
+ * a small timeout before ESC is actually delivered to the application.
+ * lxdialog suggest <ESC> <ESC> which is correctly translated to two
+ * times esc. But then we need to ignore the second esc to avoid stepping
+ * out one menu too much. Filter away all escaped key sequences since
+ * keypad(FALSE) turn off ncurses support for escape sequences - and thats
+ * needed to make notimeout() do as expected.
+ */
+int on_key_esc(WINDOW *win)
+{
+       int key;
+       int key2;
+       int key3;
+
+       nodelay(win, TRUE);
+       keypad(win, FALSE);
+       key = wgetch(win);
+       key2 = wgetch(win);
+       do {
+               key3 = wgetch(win);
+       } while (key3 != ERR);
+       nodelay(win, FALSE);
+       keypad(win, TRUE);
+       if (key == KEY_ESC && key2 == ERR)
+               return KEY_ESC;
+       else if (key != ERR && key != KEY_ESC && key2 == ERR)
+               ungetch(key);
+
+       return -1;
+}
+
+/* redraw screen in new size */
+int on_key_resize(void)
+{
+       dialog_clear();
+       return KEY_RESIZE;
+}
+
+struct dialog_list *item_cur;
+struct dialog_list item_nil;
+struct dialog_list *item_head;
+
+void item_reset(void)
+{
+       struct dialog_list *p, *next;
+
+       for (p = item_head; p; p = next) {
+               next = p->next;
+               free(p);
+       }
+       item_head = NULL;
+       item_cur = &item_nil;
+}
+
+void item_make(const char *fmt, ...)
+{
+       va_list ap;
+       struct dialog_list *p = malloc(sizeof(*p));
+
+       if (item_head)
+               item_cur->next = p;
+       else
+               item_head = p;
+       item_cur = p;
+       memset(p, 0, sizeof(*p));
+
+       va_start(ap, fmt);
+       vsnprintf(item_cur->node.str, sizeof(item_cur->node.str), fmt, ap);
+       va_end(ap);
+}
+
+void item_add_str(const char *fmt, ...)
+{
+       va_list ap;
+        size_t avail;
+
+       avail = sizeof(item_cur->node.str) - strlen(item_cur->node.str);
+
+       va_start(ap, fmt);
+       vsnprintf(item_cur->node.str + strlen(item_cur->node.str),
+                 avail, fmt, ap);
+       item_cur->node.str[sizeof(item_cur->node.str) - 1] = '\0';
+       va_end(ap);
+}
+
+void item_set_tag(char tag)
+{
+       item_cur->node.tag = tag;
+}
+void item_set_data(void *ptr)
+{
+       item_cur->node.data = ptr;
+}
+
+void item_set_selected(int val)
+{
+       item_cur->node.selected = val;
+}
+
+int item_activate_selected(void)
+{
+       item_foreach()
+               if (item_is_selected())
+                       return 1;
+       return 0;
+}
+
+void *item_data(void)
+{
+       return item_cur->node.data;
+}
+
+char item_tag(void)
+{
+       return item_cur->node.tag;
+}
+
+int item_count(void)
+{
+       int n = 0;
+       struct dialog_list *p;
+
+       for (p = item_head; p; p = p->next)
+               n++;
+       return n;
+}
+
+void item_set(int n)
+{
+       int i = 0;
+       item_foreach()
+               if (i++ == n)
+                       return;
+}
+
+int item_n(void)
+{
+       int n = 0;
+       struct dialog_list *p;
+
+       for (p = item_head; p; p = p->next) {
+               if (p == item_cur)
+                       return n;
+               n++;
+       }
+       return 0;
+}
+
+const char *item_str(void)
+{
+       return item_cur->node.str;
+}
+
+int item_is_selected(void)
+{
+       return (item_cur->node.selected != 0);
+}
+
+int item_is_tag(char tag)
+{
+       return (item_cur->node.tag == tag);
+}
index cb2568aae3ed7609a68dd04a81750e3e7c52ab2c..ee0a04e3e012ecd4ba119cd153d96a08ded7b2a2 100644 (file)
@@ -44,6 +44,12 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width)
        int i, x, y, key = 0, button = 0;
        WINDOW *dialog;
 
+do_resize:
+       if (getmaxy(stdscr) < (height + 4))
+               return -ERRDISPLAYTOOSMALL;
+       if (getmaxx(stdscr) < (width + 4))
+               return -ERRDISPLAYTOOSMALL;
+
        /* center dialog box on screen */
        x = (COLS - width) / 2;
        y = (LINES - height) / 2;
@@ -53,22 +59,23 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width)
        dialog = newwin(height, width, y, x);
        keypad(dialog, TRUE);
 
-       draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
-       wattrset(dialog, border_attr);
+       draw_box(dialog, 0, 0, height, width,
+                dlg.dialog.atr, dlg.border.atr);
+       wattrset(dialog, dlg.border.atr);
        mvwaddch(dialog, height - 3, 0, ACS_LTEE);
        for (i = 0; i < width - 2; i++)
                waddch(dialog, ACS_HLINE);
-       wattrset(dialog, dialog_attr);
+       wattrset(dialog, dlg.dialog.atr);
        waddch(dialog, ACS_RTEE);
 
        print_title(dialog, title, width);
 
-       wattrset(dialog, dialog_attr);
+       wattrset(dialog, dlg.dialog.atr);
        print_autowrap(dialog, prompt, width - 2, 1, 3);
 
        print_buttons(dialog, height, width, 0);
 
-       while (key != ESC) {
+       while (key != KEY_ESC) {
                key = wgetch(dialog);
                switch (key) {
                case 'Y':
@@ -92,11 +99,16 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width)
                case '\n':
                        delwin(dialog);
                        return button;
-               case ESC:
+               case KEY_ESC:
+                       key = on_key_esc(dialog);
                        break;
+               case KEY_RESIZE:
+                       delwin(dialog);
+                       on_key_resize();
+                       goto do_resize;
                }
        }
 
        delwin(dialog);
-       return -1;              /* ESC pressed */
+       return key;             /* ESC pressed */
 }
index 7f973195e79a05b5eaac232030b9fdcc12993b52..08a4c7af93ea0ffd9d19b9efcbf02572d7fb94ac 100644 (file)
@@ -24,6 +24,7 @@
 
 #define LKC_DIRECT_LINK
 #include "lkc.h"
+#include "lxdialog/dialog.h"
 
 static char menu_backtitle[128];
 static const char mconf_readme[] = N_(
@@ -159,7 +160,21 @@ static const char mconf_readme[] = N_(
 "\n"
 "Note that this mode can eventually be a little more CPU expensive\n"
 "(especially with a larger number of unrolled categories) than the\n"
-"default mode.\n"),
+"default mode.\n"
+"\n"
+"Different color themes available\n"
+"--------------------------------\n"
+"It is possible to select different color themes using the variable\n"
+"MENUCONFIG_COLOR. To select a theme use:\n"
+"\n"
+"make MENUCONFIG_COLOR=<theme> menuconfig\n"
+"\n"
+"Available themes are\n"
+" mono       => selects colors suitable for monochrome displays\n"
+" blackbg    => selects a color scheme with black background\n"
+" classic    => theme with blue background. The classic look\n"
+" bluetitle  => a LCD friendly version of classic. (default)\n"
+"\n"),
 menu_instructions[] = N_(
        "Arrow keys navigate the menu.  "
        "<Enter> selects submenus --->.  "
@@ -256,16 +271,12 @@ search_help[] = N_(
        "          USB$ => find all CONFIG_ symbols ending with USB\n"
        "\n");
 
-static char buf[4096], *bufptr = buf;
-static char input_buf[4096];
 static char filename[PATH_MAX+1] = ".config";
-static char *args[1024], **argptr = args;
 static int indent;
 static struct termios ios_org;
 static int rows = 0, cols = 0;
 static struct menu *current_menu;
 static int child_count;
-static int do_resize;
 static int single_menu_mode;
 
 static void conf(struct menu *menu);
@@ -276,12 +287,6 @@ static void conf_save(void);
 static void show_textbox(const char *title, const char *text, int r, int c);
 static void show_helptext(const char *title, const char *text);
 static void show_help(struct menu *menu);
-static void show_file(const char *filename, const char *title, int r, int c);
-
-static void cprint_init(void);
-static int cprint1(const char *fmt, ...);
-static void cprint_done(void);
-static int cprint(const char *fmt, ...);
 
 static void init_wsize(void)
 {
@@ -318,54 +323,6 @@ static void init_wsize(void)
        cols -= 5;
 }
 
-static void cprint_init(void)
-{
-       bufptr = buf;
-       argptr = args;
-       memset(args, 0, sizeof(args));
-       indent = 0;
-       child_count = 0;
-       cprint("./scripts/kconfig/lxdialog/lxdialog");
-       cprint("--backtitle");
-       cprint(menu_backtitle);
-}
-
-static int cprint1(const char *fmt, ...)
-{
-       va_list ap;
-       int res;
-
-       if (!*argptr)
-               *argptr = bufptr;
-       va_start(ap, fmt);
-       res = vsprintf(bufptr, fmt, ap);
-       va_end(ap);
-       bufptr += res;
-
-       return res;
-}
-
-static void cprint_done(void)
-{
-       *bufptr++ = 0;
-       argptr++;
-}
-
-static int cprint(const char *fmt, ...)
-{
-       va_list ap;
-       int res;
-
-       *argptr++ = bufptr;
-       va_start(ap, fmt);
-       res = vsprintf(bufptr, fmt, ap);
-       va_end(ap);
-       bufptr += res;
-       *bufptr++ = 0;
-
-       return res;
-}
-
 static void get_prompt_str(struct gstr *r, struct property *prop)
 {
        int i, j;
@@ -438,108 +395,17 @@ static struct gstr get_relations_str(struct symbol **sym_arr)
        return res;
 }
 
-pid_t pid;
-
-static void winch_handler(int sig)
-{
-       if (!do_resize) {
-               kill(pid, SIGINT);
-               do_resize = 1;
-       }
-}
-
-static int exec_conf(void)
-{
-       int pipefd[2], stat, size;
-       struct sigaction sa;
-       sigset_t sset, osset;
-
-       sigemptyset(&sset);
-       sigaddset(&sset, SIGINT);
-       sigprocmask(SIG_BLOCK, &sset, &osset);
-
-       signal(SIGINT, SIG_DFL);
-
-       sa.sa_handler = winch_handler;
-       sigemptyset(&sa.sa_mask);
-       sa.sa_flags = SA_RESTART;
-       sigaction(SIGWINCH, &sa, NULL);
-
-       *argptr++ = NULL;
-
-       pipe(pipefd);
-       pid = fork();
-       if (pid == 0) {
-               sigprocmask(SIG_SETMASK, &osset, NULL);
-               dup2(pipefd[1], 2);
-               close(pipefd[0]);
-               close(pipefd[1]);
-               execv(args[0], args);
-               _exit(EXIT_FAILURE);
-       }
-
-       close(pipefd[1]);
-       bufptr = input_buf;
-       while (1) {
-               size = input_buf + sizeof(input_buf) - bufptr;
-               size = read(pipefd[0], bufptr, size);
-               if (size <= 0) {
-                       if (size < 0) {
-                               if (errno == EINTR || errno == EAGAIN)
-                                       continue;
-                               perror("read");
-                       }
-                       break;
-               }
-               bufptr += size;
-       }
-       *bufptr++ = 0;
-       close(pipefd[0]);
-       waitpid(pid, &stat, 0);
-
-       if (do_resize) {
-               init_wsize();
-               do_resize = 0;
-               sigprocmask(SIG_SETMASK, &osset, NULL);
-               return -1;
-       }
-       if (WIFSIGNALED(stat)) {
-               printf("\finterrupted(%d)\n", WTERMSIG(stat));
-               exit(1);
-       }
-#if 0
-       printf("\fexit state: %d\nexit data: '%s'\n", WEXITSTATUS(stat), input_buf);
-       sleep(1);
-#endif
-       sigpending(&sset);
-       if (sigismember(&sset, SIGINT)) {
-               printf("\finterrupted\n");
-               exit(1);
-       }
-       sigprocmask(SIG_SETMASK, &osset, NULL);
-
-       return WEXITSTATUS(stat);
-}
-
 static void search_conf(void)
 {
        struct symbol **sym_arr;
-       int stat;
        struct gstr res;
-
+       int dres;
 again:
-       cprint_init();
-       cprint("--title");
-       cprint(_("Search Configuration Parameter"));
-       cprint("--inputbox");
-       cprint(_("Enter CONFIG_ (sub)string to search for (omit CONFIG_)"));
-       cprint("10");
-       cprint("75");
-       cprint("");
-       stat = exec_conf();
-       if (stat < 0)
-               goto again;
-       switch (stat) {
+       dialog_clear();
+       dres = dialog_inputbox(_("Search Configuration Parameter"),
+                             _("Enter CONFIG_ (sub)string to search for (omit CONFIG_)"),
+                             10, 75, "");
+       switch (dres) {
        case 0:
                break;
        case 1:
@@ -549,7 +415,7 @@ again:
                return;
        }
 
-       sym_arr = sym_re_search(input_buf);
+       sym_arr = sym_re_search(dialog_input_result);
        res = get_relations_str(sym_arr);
        free(sym_arr);
        show_textbox(_("Search Results"), str_get(&res), 0, 0);
@@ -576,24 +442,24 @@ static void build_conf(struct menu *menu)
                        switch (prop->type) {
                        case P_MENU:
                                child_count++;
-                               cprint("m%p", menu);
-
                                if (single_menu_mode) {
-                                       cprint1("%s%*c%s",
-                                               menu->data ? "-->" : "++>",
-                                               indent + 1, ' ', prompt);
+                                       item_make("%s%*c%s",
+                                                 menu->data ? "-->" : "++>",
+                                                 indent + 1, ' ', prompt);
                                } else
-                                       cprint1("   %*c%s  --->", indent + 1, ' ', prompt);
+                                       item_make("   %*c%s  --->", indent + 1, ' ', prompt);
 
-                               cprint_done();
+                               item_set_tag('m');
+                               item_set_data(menu);
                                if (single_menu_mode && menu->data)
                                        goto conf_childs;
                                return;
                        default:
                                if (prompt) {
                                        child_count++;
-                                       cprint(":%p", menu);
-                                       cprint("---%*c%s", indent + 1, ' ', prompt);
+                                       item_make("---%*c%s", indent + 1, ' ', prompt);
+                                       item_set_tag(':');
+                                       item_set_data(menu);
                                }
                        }
                } else
@@ -614,10 +480,9 @@ static void build_conf(struct menu *menu)
 
                val = sym_get_tristate_value(sym);
                if (sym_is_changable(sym)) {
-                       cprint("t%p", menu);
                        switch (type) {
                        case S_BOOLEAN:
-                               cprint1("[%c]", val == no ? ' ' : '*');
+                               item_make("[%c]", val == no ? ' ' : '*');
                                break;
                        case S_TRISTATE:
                                switch (val) {
@@ -625,84 +490,87 @@ static void build_conf(struct menu *menu)
                                case mod: ch = 'M'; break;
                                default:  ch = ' '; break;
                                }
-                               cprint1("<%c>", ch);
+                               item_make("<%c>", ch);
                                break;
                        }
+                       item_set_tag('t');
+                       item_set_data(menu);
                } else {
-                       cprint("%c%p", def_menu ? 't' : ':', menu);
-                       cprint1("   ");
+                       item_make("   ");
+                       item_set_tag(def_menu ? 't' : ':');
+                       item_set_data(menu);
                }
 
-               cprint1("%*c%s", indent + 1, ' ', menu_get_prompt(menu));
+               item_add_str("%*c%s", indent + 1, ' ', menu_get_prompt(menu));
                if (val == yes) {
                        if (def_menu) {
-                               cprint1(" (%s)", menu_get_prompt(def_menu));
-                               cprint1("  --->");
-                               cprint_done();
+                               item_add_str(" (%s)", menu_get_prompt(def_menu));
+                               item_add_str("  --->");
                                if (def_menu->list) {
                                        indent += 2;
                                        build_conf(def_menu);
                                        indent -= 2;
                                }
-                       } else
-                               cprint_done();
+                       }
                        return;
                }
-               cprint_done();
        } else {
                if (menu == current_menu) {
-                       cprint(":%p", menu);
-                       cprint("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));
+                       item_make("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));
+                       item_set_tag(':');
+                       item_set_data(menu);
                        goto conf_childs;
                }
                child_count++;
                val = sym_get_tristate_value(sym);
                if (sym_is_choice_value(sym) && val == yes) {
-                       cprint(":%p", menu);
-                       cprint1("   ");
+                       item_make("   ");
+                       item_set_tag(':');
+                       item_set_data(menu);
                } else {
                        switch (type) {
                        case S_BOOLEAN:
-                               cprint("t%p", menu);
                                if (sym_is_changable(sym))
-                                       cprint1("[%c]", val == no ? ' ' : '*');
+                                       item_make("[%c]", val == no ? ' ' : '*');
                                else
-                                       cprint1("---");
+                                       item_make("---");
+                               item_set_tag('t');
+                               item_set_data(menu);
                                break;
                        case S_TRISTATE:
-                               cprint("t%p", menu);
                                switch (val) {
                                case yes: ch = '*'; break;
                                case mod: ch = 'M'; break;
                                default:  ch = ' '; break;
                                }
                                if (sym_is_changable(sym))
-                                       cprint1("<%c>", ch);
+                                       item_make("<%c>", ch);
                                else
-                                       cprint1("---");
+                                       item_make("---");
+                               item_set_tag('t');
+                               item_set_data(menu);
                                break;
                        default:
-                               cprint("s%p", menu);
-                               tmp = cprint1("(%s)", sym_get_string_value(sym));
+                               tmp = 2 + strlen(sym_get_string_value(sym)); /* () = 2 */
+                               item_make("(%s)", sym_get_string_value(sym));
                                tmp = indent - tmp + 4;
                                if (tmp < 0)
                                        tmp = 0;
-                               cprint1("%*c%s%s", tmp, ' ', menu_get_prompt(menu),
-                                       (sym_has_value(sym) || !sym_is_changable(sym)) ?
-                                       "" : " (NEW)");
-                               cprint_done();
+                               item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu),
+                                            (sym_has_value(sym) || !sym_is_changable(sym)) ?
+                                            "" : " (NEW)");
+                               item_set_tag('s');
+                               item_set_data(menu);
                                goto conf_childs;
                        }
                }
-               cprint1("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),
-                       (sym_has_value(sym) || !sym_is_changable(sym)) ?
-                       "" : " (NEW)");
+               item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),
+                         (sym_has_value(sym) || !sym_is_changable(sym)) ?
+                         "" : " (NEW)");
                if (menu->prompt->type == P_MENU) {
-                       cprint1("  --->");
-                       cprint_done();
+                       item_add_str("  --->");
                        return;
                }
-               cprint_done();
        }
 
 conf_childs:
@@ -717,59 +585,45 @@ static void conf(struct menu *menu)
        struct menu *submenu;
        const char *prompt = menu_get_prompt(menu);
        struct symbol *sym;
-       char active_entry[40];
-       int stat, type, i;
+       struct menu *active_menu = NULL;
+       int res;
+       int s_scroll = 0;
 
-       unlink("lxdialog.scrltmp");
-       active_entry[0] = 0;
        while (1) {
-               cprint_init();
-               cprint("--title");
-               cprint("%s", prompt ? prompt : _("Main Menu"));
-               cprint("--menu");
-               cprint(_(menu_instructions));
-               cprint("%d", rows);
-               cprint("%d", cols);
-               cprint("%d", rows - 10);
-               cprint("%s", active_entry);
+               item_reset();
                current_menu = menu;
                build_conf(menu);
                if (!child_count)
                        break;
                if (menu == &rootmenu) {
-                       cprint(":");
-                       cprint("--- ");
-                       cprint("L");
-                       cprint(_("    Load an Alternate Configuration File"));
-                       cprint("S");
-                       cprint(_("    Save Configuration to an Alternate File"));
+                       item_make("--- ");
+                       item_set_tag(':');
+                       item_make(_("    Load an Alternate Configuration File"));
+                       item_set_tag('L');
+                       item_make(_("    Save an Alternate Configuration File"));
+                       item_set_tag('S');
                }
-               stat = exec_conf();
-               if (stat < 0)
-                       continue;
-
-               if (stat == 1 || stat == 255)
+               dialog_clear();
+               res = dialog_menu(prompt ? prompt : _("Main Menu"),
+                                 _(menu_instructions),
+                                 active_menu, &s_scroll);
+               if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
                        break;
-
-               type = input_buf[0];
-               if (!type)
+               if (!item_activate_selected())
+                       continue;
+               if (!item_tag())
                        continue;
 
-               for (i = 0; input_buf[i] && !isspace(input_buf[i]); i++)
-                       ;
-               if (i >= sizeof(active_entry))
-                       i = sizeof(active_entry) - 1;
-               input_buf[i] = 0;
-               strcpy(active_entry, input_buf);
-
-               sym = NULL;
-               submenu = NULL;
-               if (sscanf(input_buf + 1, "%p", &submenu) == 1)
+               submenu = item_data();
+               active_menu = item_data();
+               if (submenu)
                        sym = submenu->sym;
+               else
+                       sym = NULL;
 
-               switch (stat) {
+               switch (res) {
                case 0:
-                       switch (type) {
+                       switch (item_tag()) {
                        case 'm':
                                if (single_menu_mode)
                                        submenu->data = (void *) (long) !submenu->data;
@@ -800,7 +654,7 @@ static void conf(struct menu *menu)
                                show_helptext("README", _(mconf_readme));
                        break;
                case 3:
-                       if (type == 't') {
+                       if (item_is_tag('t')) {
                                if (sym_set_tristate_value(sym, yes))
                                        break;
                                if (sym_set_tristate_value(sym, mod))
@@ -808,17 +662,17 @@ static void conf(struct menu *menu)
                        }
                        break;
                case 4:
-                       if (type == 't')
+                       if (item_is_tag('t'))
                                sym_set_tristate_value(sym, no);
                        break;
                case 5:
-                       if (type == 't')
+                       if (item_is_tag('t'))
                                sym_set_tristate_value(sym, mod);
                        break;
                case 6:
-                       if (type == 't')
+                       if (item_is_tag('t'))
                                sym_toggle_tristate_value(sym);
-                       else if (type == 'm')
+                       else if (item_is_tag('m'))
                                conf(submenu);
                        break;
                case 7:
@@ -830,13 +684,8 @@ static void conf(struct menu *menu)
 
 static void show_textbox(const char *title, const char *text, int r, int c)
 {
-       int fd;
-
-       fd = creat(".help.tmp", 0777);
-       write(fd, text, strlen(text));
-       close(fd);
-       show_file(".help.tmp", title, r, c);
-       unlink(".help.tmp");
+       dialog_clear();
+       dialog_textbox(title, text, r, c);
 }
 
 static void show_helptext(const char *title, const char *text)
@@ -864,68 +713,52 @@ static void show_help(struct menu *menu)
        str_free(&help);
 }
 
-static void show_file(const char *filename, const char *title, int r, int c)
-{
-       do {
-               cprint_init();
-               if (title) {
-                       cprint("--title");
-                       cprint("%s", title);
-               }
-               cprint("--textbox");
-               cprint("%s", filename);
-               cprint("%d", r ? r : rows);
-               cprint("%d", c ? c : cols);
-       } while (exec_conf() < 0);
-}
-
 static void conf_choice(struct menu *menu)
 {
        const char *prompt = menu_get_prompt(menu);
        struct menu *child;
        struct symbol *active;
-       int stat;
 
        active = sym_get_choice_value(menu->sym);
        while (1) {
-               cprint_init();
-               cprint("--title");
-               cprint("%s", prompt ? prompt : _("Main Menu"));
-               cprint("--radiolist");
-               cprint(_(radiolist_instructions));
-               cprint("15");
-               cprint("70");
-               cprint("6");
+               int res;
+               int selected;
+               item_reset();
 
                current_menu = menu;
                for (child = menu->list; child; child = child->next) {
                        if (!menu_is_visible(child))
                                continue;
-                       cprint("%p", child);
-                       cprint("%s", menu_get_prompt(child));
+                       item_make("%s", menu_get_prompt(child));
+                       item_set_data(child);
+                       if (child->sym == active)
+                               item_set_selected(1);
                        if (child->sym == sym_get_choice_value(menu->sym))
-                               cprint("ON");
-                       else if (child->sym == active)
-                               cprint("SELECTED");
-                       else
-                               cprint("OFF");
+                               item_set_tag('X');
                }
-
-               stat = exec_conf();
-               switch (stat) {
+               dialog_clear();
+               res = dialog_checklist(prompt ? prompt : _("Main Menu"),
+                                       _(radiolist_instructions),
+                                        15, 70, 6);
+               selected = item_activate_selected();
+               switch (res) {
                case 0:
-                       if (sscanf(input_buf, "%p", &child) != 1)
-                               break;
-                       sym_set_tristate_value(child->sym, yes);
+                       if (selected) {
+                               child = item_data();
+                               sym_set_tristate_value(child->sym, yes);
+                       }
                        return;
                case 1:
-                       if (sscanf(input_buf, "%p", &child) == 1) {
+                       if (selected) {
+                               child = item_data();
                                show_help(child);
                                active = child->sym;
                        } else
                                show_help(menu);
                        break;
-               case 255:
+               case KEY_ESC:
+                       return;
+               case -ERRDISPLAYTOOSMALL:
                        return;
                }
        }
@@ -934,40 +767,38 @@ static void conf_choice(struct menu *menu)
 static void conf_string(struct menu *menu)
 {
        const char *prompt = menu_get_prompt(menu);
-       int stat;
 
        while (1) {
-               cprint_init();
-               cprint("--title");
-               cprint("%s", prompt ? prompt : _("Main Menu"));
-               cprint("--inputbox");
+               int res;
+               char *heading;
+
                switch (sym_get_type(menu->sym)) {
                case S_INT:
-                       cprint(_(inputbox_instructions_int));
+                       heading = _(inputbox_instructions_int);
                        break;
                case S_HEX:
-                       cprint(_(inputbox_instructions_hex));
+                       heading = _(inputbox_instructions_hex);
                        break;
                case S_STRING:
-                       cprint(_(inputbox_instructions_string));
+                       heading = _(inputbox_instructions_string);
                        break;
                default:
-                       /* panic? */;
+                       heading = "Internal mconf error!";
                }
-               cprint("10");
-               cprint("75");
-               cprint("%s", sym_get_string_value(menu->sym));
-               stat = exec_conf();
-               switch (stat) {
+               dialog_clear();
+               res = dialog_inputbox(prompt ? prompt : _("Main Menu"),
+                                     heading, 10, 75,
+                                     sym_get_string_value(menu->sym));
+               switch (res) {
                case 0:
-                       if (sym_set_string_value(menu->sym, input_buf))
+                       if (sym_set_string_value(menu->sym, dialog_input_result))
                                return;
                        show_textbox(NULL, _("You have made an invalid entry."), 5, 43);
                        break;
                case 1:
                        show_help(menu);
                        break;
-               case 255:
+               case KEY_ESC:
                        return;
                }
        }
@@ -975,28 +806,24 @@ static void conf_string(struct menu *menu)
 
 static void conf_load(void)
 {
-       int stat;
 
        while (1) {
-               cprint_init();
-               cprint("--inputbox");
-               cprint(load_config_text);
-               cprint("11");
-               cprint("55");
-               cprint("%s", filename);
-               stat = exec_conf();
-               switch(stat) {
+               int res;
+               dialog_clear();
+               res = dialog_inputbox(NULL, load_config_text,
+                                     11, 55, filename);
+               switch(res) {
                case 0:
-                       if (!input_buf[0])
+                       if (!dialog_input_result[0])
                                return;
-                       if (!conf_read(input_buf))
+                       if (!conf_read(dialog_input_result))
                                return;
                        show_textbox(NULL, _("File does not exist!"), 5, 38);
                        break;
                case 1:
                        show_helptext(_("Load Alternate Configuration"), load_config_help);
                        break;
-               case 255:
+               case KEY_ESC:
                        return;
                }
        }
@@ -1004,28 +831,23 @@ static void conf_load(void)
 
 static void conf_save(void)
 {
-       int stat;
-
        while (1) {
-               cprint_init();
-               cprint("--inputbox");
-               cprint(save_config_text);
-               cprint("11");
-               cprint("55");
-               cprint("%s", filename);
-               stat = exec_conf();
-               switch(stat) {
+               int res;
+               dialog_clear();
+               res = dialog_inputbox(NULL, save_config_text,
+                                     11, 55, filename);
+               switch(res) {
                case 0:
-                       if (!input_buf[0])
+                       if (!dialog_input_result[0])
                                return;
-                       if (!conf_write(input_buf))
+                       if (!conf_write(dialog_input_result))
                                return;
                        show_textbox(NULL, _("Can't create file!  Probably a nonexistent directory."), 5, 60);
                        break;
                case 1:
                        show_helptext(_("Save Alternate Configuration"), save_config_help);
                        break;
-               case 255:
+               case KEY_ESC:
                        return;
                }
        }
@@ -1034,15 +856,13 @@ static void conf_save(void)
 static void conf_cleanup(void)
 {
        tcsetattr(1, TCSAFLUSH, &ios_org);
-       unlink(".help.tmp");
-       unlink("lxdialog.scrltmp");
 }
 
 int main(int ac, char **av)
 {
        struct symbol *sym;
        char *mode;
-       int stat;
+       int res;
 
        setlocale(LC_ALL, "");
        bindtextdomain(PACKAGE, LOCALEDIR);
@@ -1065,18 +885,19 @@ int main(int ac, char **av)
        tcgetattr(1, &ios_org);
        atexit(conf_cleanup);
        init_wsize();
-       conf(&rootmenu);
-
+       reset_dialog();
+       init_dialog(menu_backtitle);
        do {
-               cprint_init();
-               cprint("--yesno");
-               cprint(_("Do you wish to save your new kernel configuration?"));
-               cprint("5");
-               cprint("60");
-               stat = exec_conf();
-       } while (stat < 0);
-
-       if (stat == 0) {
+               conf(&rootmenu);
+               dialog_clear();
+               res = dialog_yesno(NULL,
+                                  _("Do you wish to save your "
+                                    "new kernel configuration?\n"
+                                    "<ESC><ESC> to continue."),
+                                  6, 60);
+       } while (res == KEY_ESC);
+       end_dialog();
+       if (res == 0) {
                if (conf_write(NULL)) {
                        fprintf(stderr, _("\n\n"
                                "Error during writing of the kernel configuration.\n"
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 3ebc34919c76fc746a12643135b73d9c0f5b2435..a444bfe2cf7417245014562a20b06791006dbaab 100644 (file)
@@ -96,11 +96,11 @@ static void snd_sndstat_proc_read(struct snd_info_entry *entry,
 {
        snd_iprintf(buffer, "Sound Driver:3.8.1a-980706 (ALSA v" CONFIG_SND_VERSION " emulation code)\n");
        snd_iprintf(buffer, "Kernel: %s %s %s %s %s\n",
-                   system_utsname.sysname,
-                   system_utsname.nodename,
-                   system_utsname.release,
-                   system_utsname.version,
-                   system_utsname.machine);
+                   init_utsname()->sysname,
+                   init_utsname()->nodename,
+                   init_utsname()->release,
+                   init_utsname()->version,
+                   init_utsname()->machine);
        snd_iprintf(buffer, "Config options: 0\n");
        snd_iprintf(buffer, "\nInstalled drivers: \n");
        snd_iprintf(buffer, "Type 10: ALSA emulation\n");
index 97e38b66558720eae20d178b4c13dfc96d17eaec..cc2b9ab7f4e5355d490aeebff240240b2a9446f1 100644 (file)
@@ -115,10 +115,6 @@ config SOUND_HAL2
          Say Y or M if you have an SGI Indy or Indigo2 system and want to be able to
          use its on-board A2 audio system.
 
-config SOUND_IT8172
-       tristate "IT8172G Sound"
-       depends on SOUND_PRIME && (MIPS_ITE8172 || MIPS_IVR)
-
 config SOUND_VRC5477
        tristate "NEC Vrc5477 AC97 sound"
        depends on SOUND_PRIME && DDB5477
@@ -647,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 9bf3ee544d86e62987c2d23e20bea83b5bfcd0c2..2489bd6bb08561ab5e8cc296eca87d20427a354b 100644 (file)
@@ -15,72 +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_IT8172)     += ite8172.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)
@@ -88,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
@@ -119,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/ite8172.c b/sound/oss/ite8172.c
deleted file mode 100644 (file)
index 68aab36..0000000
+++ /dev/null
@@ -1,2261 +0,0 @@
-/*
- *      ite8172.c  --  ITE IT8172G Sound Driver.
- *
- * 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.
- *  2. The following support is untested:
- *      * Memory mapping the audio buffers, and the ioctl controls that go
- *        with it.
- *      * S/PDIF output.
- *      * I2S support.
- *  3. The following is not supported:
- *      * legacy audio mode.
- *  4. Support for volume button interrupts is implemented but doesn't
- *     work yet.
- *
- *  Revision history
- *    02.08.2001  Initial release
- *    06.22.2001  Added I2S support
- *    07.30.2003  Removed initialisation to zero for static variables
- *                (spdif[NR_DEVICE], i2s_fmt[NR_DEVICE], and devindex)
- */
-#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/init.h>
-#include <linux/poll.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/dma.h>
-#include <asm/uaccess.h>
-#include <asm/it8172/it8172.h>
-
-/* --------------------------------------------------------------------- */
-
-#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-#define IT8172_DEBUG
-#undef IT8172_VERBOSE_DEBUG
-#define DBG(x) {}
-
-#define IT8172_MODULE_NAME "IT8172 audio"
-#define PFX IT8172_MODULE_NAME
-
-#ifdef IT8172_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)
-
-
-#define IT8172_MODULE_NAME "IT8172 audio"
-#define PFX IT8172_MODULE_NAME
-
-#ifdef IT8172_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)
-
-
-static const unsigned sample_shift[] = { 0, 1, 1, 2 };
-
-
-/*
- * Audio Controller register bit definitions follow. See
- * include/asm/it8172/it8172.h for register offsets.
- */
-
-/* PCM Out Volume Reg */
-#define PCMOV_PCMOM    (1<<15) /* PCM Out Mute default 1: mute */
-#define        PCMOV_PCMRCG_BIT 8      /* PCM Right channel Gain */
-#define        PCMOV_PCMRCG_MASK (0x1f<<PCMOV_PCMRCG_BIT)
-#define PCMOV_PCMLCG_BIT 0     /* PCM Left channel gain  */
-#define PCMOV_PCMLCG_MASK 0x1f
-
-/* FM Out Volume Reg */
-#define FMOV_FMOM       (1<<15)        /* FM Out Mute default 1: mute */
-#define        FMOV_FMRCG_BIT  8       /* FM Right channel Gain */
-#define        FMOV_FMRCG_MASK (0x1f<<FMOV_FMRCG_BIT)
-#define FMOV_FMLCG_BIT 0       /* FM Left channel gain  */
-#define FMOV_FMLCG_MASK 0x1f
-
-/* I2S Out Volume Reg */
-#define I2SV_I2SOM      (1<<15) /* I2S Out Mute default 1: mute */
-#define        I2SV_I2SRCG_BIT  8       /* I2S Right channel Gain */
-#define        I2SV_I2SRCG_MASK (0x1f<<I2SV_I2SRCG_BIT)
-#define I2SV_I2SLCG_BIT         0       /* I2S Left channel gain  */
-#define I2SV_I2SLCG_MASK 0x1f
-
-/* Digital Recording Source Select Reg */
-#define        DRSS_BIT   0
-#define        DRSS_MASK  0x07
-#define   DRSS_AC97_PRIM 0
-#define   DRSS_FM        1
-#define   DRSS_I2S       2
-#define   DRSS_PCM       3
-#define   DRSS_AC97_SEC  4
-
-/* Playback/Capture Channel Control Registers */
-#define        CC_SM           (1<<15) /* Stereo, Mone 0: mono 1: stereo */
-#define        CC_DF           (1<<14) /* Data Format 0: 8 bit 1: 16 bit */
-#define CC_FMT_BIT      14
-#define CC_FMT_MASK     (0x03<<CC_FMT_BIT)
-#define CC_CF_BIT       12      /* Channel format (Playback only) */
-#define CC_CF_MASK      (0x03<<CC_CF_BIT)
-#define          CC_CF_2       0
-#define   CC_CF_4      (1<<CC_CF_BIT)
-#define   CC_CF_6      (2<<CC_CF_BIT)
-#define CC_SR_BIT       8       /* sample Rate */
-#define CC_SR_MASK      (0x0f<<CC_SR_BIT)
-#define          CC_SR_5500    0
-#define          CC_SR_8000    (1<<CC_SR_BIT)
-#define          CC_SR_9600    (2<<CC_SR_BIT)
-#define          CC_SR_11025   (3<<CC_SR_BIT)
-#define          CC_SR_16000   (4<<CC_SR_BIT)
-#define          CC_SR_19200   (5<<CC_SR_BIT)
-#define          CC_SR_22050   (6<<CC_SR_BIT)
-#define          CC_SR_32000   (7<<CC_SR_BIT)
-#define          CC_SR_38400   (8<<CC_SR_BIT)
-#define          CC_SR_44100   (9<<CC_SR_BIT)
-#define          CC_SR_48000   (10<<CC_SR_BIT)
-#define        CC_CSP          (1<<7)  /* Channel stop 
-                                * 0: End of Current buffer
-                                * 1: Immediately stop when rec stop */
-#define CC_CP          (1<<6)  /* Channel pause 0: normal, 1: pause */
-#define        CC_CA           (1<<5)  /* Channel Action 0: Stop , 1: start */
-#define        CC_CB2L         (1<<2)  /* Cur. buf. 2 xfr is last 0: No, 1: Yes */
-#define CC_CB1L         (1<<1) /* Cur. buf. 1 xfr is last 0: No, 1: Yes */
-#define CC_DE          1       /* DFC/DFIFO Data Empty 1: empty, 0: not empty
-                                * (Playback only)
-                                */
-
-/* Codec Control Reg */
-#define CODECC_GME     (1<<9)  /* AC97 GPIO Mode enable */
-#define        CODECC_ATM      (1<<8)  /* AC97 ATE test mode 0: test 1: normal */
-#define        CODECC_WR       (1<<6)  /* AC97 Warn reset 1: warm reset , 0: Normal */
-#define        CODECC_CR       (1<<5)  /* AC97 Cold reset 1: Cold reset , 0: Normal */
-
-
-/* I2S Control Reg     */
-#define        I2SMC_SR_BIT     6      /* I2S Sampling rate 
-                                * 00: 48KHz, 01: 44.1 KHz, 10: 32 32 KHz */
-#define        I2SMC_SR_MASK    (0x03<<I2SMC_SR_BIT)
-#define          I2SMC_SR_48000 0
-#define          I2SMC_SR_44100 (1<<I2SMC_SR_BIT)
-#define          I2SMC_SR_32000 (2<<I2SMC_SR_BIT)
-#define        I2SMC_SRSS       (1<<5) /* Sample Rate Source Select 1:S/W, 0: H/W */
-#define I2SMC_I2SF_BIT  0      /* I2S Format */
-#define I2SMC_I2SF_MASK  0x03
-#define   I2SMC_I2SF_DAC 0
-#define   I2SMC_I2SF_ADC 2
-#define   I2SMC_I2SF_I2S 3
-
-
-/* Volume up, Down, Mute */
-#define        VS_VMP  (1<<2)  /* Volume mute 1: pushed, 0: not */
-#define        VS_VDP  (1<<1)  /* Volume Down 1: pushed, 0: not */
-#define VS_VUP 1       /* Volime Up 1: pushed, 0: not */
-
-/* SRC, Mixer test control/DFC status reg */
-#define SRCS_DPUSC      (1<<5) /* DFC Playback underrun Status/clear */
-#define        SRCS_DCOSC      (1<<4)  /* DFC Capture Overrun Status/clear */
-#define SRCS_SIS       (1<<3)  /* SRC input select 1: Mixer, 0: Codec I/F */
-#define SRCS_CDIS_BIT  0       /* Codec Data Input Select */
-#define SRCS_CDIS_MASK  0x07
-#define   SRCS_CDIS_MIXER 0
-#define   SRCS_CDIS_PCM   1
-#define   SRCS_CDIS_I2S   2
-#define   SRCS_CDIS_FM    3
-#define   SRCS_CDIS_DFC   4
-
-
-/* Codec Index Reg command Port */
-#define CIRCP_CID_BIT   10
-#define CIRCP_CID_MASK  (0x03<<CIRCP_CID_BIT)
-#define CIRCP_CPS      (1<<9)  /* Command Port Status 0: ready, 1: busy */
-#define        CIRCP_DPVF      (1<<8)  /* Data Port Valid Flag 0: invalis, 1: valid */
-#define CIRCP_RWC      (1<<7)  /* Read/write command */
-#define CIRCP_CIA_BIT   0
-#define CIRCP_CIA_MASK  0x007F /* Codec Index Address */
-
-/* Test Mode Control/Test group Select Control */
-
-/* General Control Reg */
-#define GC_VDC_BIT     6       /* Volume Division Control */
-#define GC_VDC_MASK     (0x03<<GC_VDC_BIT)
-#define   GC_VDC_NONE   0
-#define   GC_VDC_DIV2   (1<<GC_VDC_BIT)
-#define   GC_VDC_DIV4   (2<<GC_VDC_BIT)
-#define        GC_SOE          (1<<2)  /* S/PDIF Output enable */
-#define        GC_SWR          1       /* Software warn reset */
-
-/* Interrupt mask Control Reg */
-#define        IMC_VCIM        (1<<6)  /* Volume CNTL interrupt mask */
-#define        IMC_CCIM        (1<<1)  /* Capture Chan. iterrupt mask */
-#define        IMC_PCIM        1       /* Playback Chan. interrupt mask */
-
-/* Interrupt status/clear reg */
-#define        ISC_VCI         (1<<6)  /* Volume CNTL interrupt 1: clears */
-#define        ISC_CCI         (1<<1)  /* Capture Chan. interrupt 1: clears  */
-#define        ISC_PCI         1       /* Playback Chan. interrupt 1: clears */
-
-/* misc stuff */
-#define POLL_COUNT   0x5000
-
-
-/* --------------------------------------------------------------------- */
-
-/*
- * Define DIGITAL1 as the I2S channel, since it is not listed in
- * soundcard.h.
- */
-#define SOUND_MIXER_I2S        SOUND_MIXER_DIGITAL1
-#define SOUND_MASK_I2S         SOUND_MASK_DIGITAL1
-#define SOUND_MIXER_READ_I2S   MIXER_READ(SOUND_MIXER_I2S)
-#define SOUND_MIXER_WRITE_I2S  MIXER_WRITE(SOUND_MIXER_I2S)
-
-/* --------------------------------------------------------------------- */
-
-struct it8172_state {
-       /* list of it8172 devices */
-       struct list_head devs;
-
-       /* the corresponding pci_dev structure */
-       struct pci_dev *dev;
-
-       /* soundcore stuff */
-       int dev_audio;
-
-       /* hardware resources */
-       unsigned long io;
-       unsigned int irq;
-
-       /* PCI ID's */
-       u16 vendor;
-       u16 device;
-       u8 rev; /* the chip revision */
-
-       /* options */
-       int spdif_volume; /* S/PDIF output is enabled if != -1 */
-       int i2s_volume;   /* current I2S out volume, in OSS format */
-       int i2s_recording;/* 1 = recording from I2S, 0 = not */
-    
-#ifdef IT8172_DEBUG
-       /* debug /proc entry */
-       struct proc_dir_entry *ps;
-       struct proc_dir_entry *ac97_ps;
-#endif /* IT8172_DEBUG */
-
-       struct ac97_codec codec;
-
-       unsigned short pcc, capcc;
-       unsigned dacrate, adcrate;
-
-       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;
-               void* nextIn;
-               void* nextOut;
-               int count;
-               int curBufPtr;
-               unsigned total_bytes;
-               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 stopped:1;
-               unsigned ossfragshift;
-               int ossmaxfrags;
-               unsigned subdivision;
-       } dma_dac, dma_adc;
-};
-
-/* --------------------------------------------------------------------- */
-
-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 it8172_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 unsigned short
-get_compat_rate(unsigned* rate)
-{
-       unsigned rate_out = *rate;
-       unsigned short sr;
-    
-       if (rate_out >= 46050) {
-               sr = CC_SR_48000; rate_out = 48000;
-       } else if (rate_out >= 41250) {
-               sr = CC_SR_44100; rate_out = 44100;
-       } else if (rate_out >= 35200) {
-               sr = CC_SR_38400; rate_out = 38400;
-       } else if (rate_out >= 27025) {
-               sr = CC_SR_32000; rate_out = 32000;
-       } else if (rate_out >= 20625) {
-               sr = CC_SR_22050; rate_out = 22050;
-       } else if (rate_out >= 17600) {
-               sr = CC_SR_19200; rate_out = 19200;
-       } else if (rate_out >= 13513) {
-               sr = CC_SR_16000; rate_out = 16000;
-       } else if (rate_out >= 10313) {
-               sr = CC_SR_11025; rate_out = 11025;
-       } else if (rate_out >= 8800) {
-               sr = CC_SR_9600; rate_out = 9600;
-       } else if (rate_out >= 6750) {
-               sr = CC_SR_8000; rate_out = 8000;
-       } else {
-               sr = CC_SR_5500; rate_out = 5500;
-       }
-
-       *rate = rate_out;
-       return sr;
-}
-
-static void set_adc_rate(struct it8172_state *s, unsigned rate)
-{
-       unsigned long flags;
-       unsigned short sr;
-    
-       sr = get_compat_rate(&rate);
-
-       spin_lock_irqsave(&s->lock, flags);
-       s->capcc &= ~CC_SR_MASK;
-       s->capcc |= sr;
-       outw(s->capcc, s->io+IT_AC_CAPCC);
-       spin_unlock_irqrestore(&s->lock, flags);
-
-       s->adcrate = rate;
-}
-
-
-static void set_dac_rate(struct it8172_state *s, unsigned rate)
-{
-       unsigned long flags;
-       unsigned short sr;
-    
-       sr = get_compat_rate(&rate);
-
-       spin_lock_irqsave(&s->lock, flags);
-       s->pcc &= ~CC_SR_MASK;
-       s->pcc |= sr;
-       outw(s->pcc, s->io+IT_AC_PCC);
-       spin_unlock_irqrestore(&s->lock, flags);
-
-       s->dacrate = rate;
-}
-
-
-/* --------------------------------------------------------------------- */
-
-static u16 rdcodec(struct ac97_codec *codec, u8 addr)
-{
-       struct it8172_state *s = (struct it8172_state *)codec->private_data;
-       unsigned long flags;
-       unsigned short circp, data;
-       int i;
-    
-       spin_lock_irqsave(&s->lock, flags);
-
-       for (i = 0; i < POLL_COUNT; i++)
-               if (!(inw(s->io+IT_AC_CIRCP) & CIRCP_CPS))
-                       break;
-       if (i == POLL_COUNT)
-               err("rdcodec: codec ready poll expired!");
-
-       circp = addr & CIRCP_CIA_MASK;
-       circp |= (codec->id << CIRCP_CID_BIT);
-       circp |= CIRCP_RWC; // read command
-       outw(circp, s->io+IT_AC_CIRCP);
-
-       /* now wait for the data */
-       for (i = 0; i < POLL_COUNT; i++)
-               if (inw(s->io+IT_AC_CIRCP) & CIRCP_DPVF)
-                       break;
-       if (i == POLL_COUNT)
-               err("rdcodec: read poll expired!");
-
-       data = inw(s->io+IT_AC_CIRDP);
-       spin_unlock_irqrestore(&s->lock, flags);
-
-       return data;
-}
-
-
-static void wrcodec(struct ac97_codec *codec, u8 addr, u16 data)
-{
-       struct it8172_state *s = (struct it8172_state *)codec->private_data;
-       unsigned long flags;
-       unsigned short circp;
-       int i;
-    
-       spin_lock_irqsave(&s->lock, flags);
-
-       for (i = 0; i < POLL_COUNT; i++)
-               if (!(inw(s->io+IT_AC_CIRCP) & CIRCP_CPS))
-                       break;
-       if (i == POLL_COUNT)
-               err("wrcodec: codec ready poll expired!");
-
-       circp = addr & CIRCP_CIA_MASK;
-       circp |= (codec->id << CIRCP_CID_BIT);
-       circp &= ~CIRCP_RWC; // write command
-
-       outw(data,  s->io+IT_AC_CIRDP);  // send data first
-       outw(circp, s->io+IT_AC_CIRCP);
-
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-
-static void waitcodec(struct ac97_codec *codec)
-{
-       unsigned short temp;
-
-       /* codec_wait is used to wait for a ready state after
-          an AC97_RESET. */
-       it8172_delay(10);
-
-       temp = rdcodec(codec, 0x26);
-
-       // If power down, power up
-       if (temp & 0x3f00) {
-               // Power on
-               wrcodec(codec, 0x26, 0);
-               it8172_delay(100);
-               // Reread
-               temp = rdcodec(codec, 0x26);
-       }
-    
-       // Check if Codec REF,ANL,DAC,ADC ready***/
-       if ((temp & 0x3f0f) != 0x000f) {
-               err("codec reg 26 status (0x%x) not ready!!", temp);
-               return;
-       }
-}
-
-
-/* --------------------------------------------------------------------- */
-
-static inline void stop_adc(struct it8172_state *s)
-{
-       struct dmabuf* db = &s->dma_adc;
-       unsigned long flags;
-       unsigned char imc;
-    
-       if (db->stopped)
-               return;
-
-       spin_lock_irqsave(&s->lock, flags);
-
-       s->capcc &= ~(CC_CA | CC_CP | CC_CB2L | CC_CB1L);
-       s->capcc |= CC_CSP;
-       outw(s->capcc, s->io+IT_AC_CAPCC);
-    
-       // disable capture interrupt
-       imc = inb(s->io+IT_AC_IMC);
-       outb(imc | IMC_CCIM, s->io+IT_AC_IMC);
-
-       db->stopped = 1;
-
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static inline void stop_dac(struct it8172_state *s)
-{
-       struct dmabuf* db = &s->dma_dac;
-       unsigned long flags;
-       unsigned char imc;
-    
-       if (db->stopped)
-               return;
-
-       spin_lock_irqsave(&s->lock, flags);
-
-       s->pcc &= ~(CC_CA | CC_CP | CC_CB2L | CC_CB1L);
-       s->pcc |= CC_CSP;
-       outw(s->pcc, s->io+IT_AC_PCC);
-    
-       // disable playback interrupt
-       imc = inb(s->io+IT_AC_IMC);
-       outb(imc | IMC_PCIM, s->io+IT_AC_IMC);
-
-       db->stopped = 1;
-    
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static void start_dac(struct it8172_state *s)
-{
-       struct dmabuf* db = &s->dma_dac;
-       unsigned long flags;
-       unsigned char imc;
-       unsigned long buf1, buf2;
-    
-       if (!db->stopped)
-               return;
-    
-       spin_lock_irqsave(&s->lock, flags);
-
-       // reset Buffer 1 and 2 pointers to nextOut and nextOut+fragsize
-       buf1 = virt_to_bus(db->nextOut);
-       buf2 = buf1 + db->fragsize;
-       if (buf2 >= db->dmaaddr + db->dmasize)
-               buf2 -= db->dmasize;
-    
-       outl(buf1, s->io+IT_AC_PCB1STA);
-       outl(buf2, s->io+IT_AC_PCB2STA);
-       db->curBufPtr = IT_AC_PCB1STA;
-    
-       // enable playback interrupt
-       imc = inb(s->io+IT_AC_IMC);
-       outb(imc & ~IMC_PCIM, s->io+IT_AC_IMC);
-
-       s->pcc &= ~(CC_CSP | CC_CP | CC_CB2L | CC_CB1L);
-       s->pcc |= CC_CA;
-       outw(s->pcc, s->io+IT_AC_PCC);
-    
-       db->stopped = 0;
-
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static void start_adc(struct it8172_state *s)
-{
-       struct dmabuf* db = &s->dma_adc;
-       unsigned long flags;
-       unsigned char imc;
-       unsigned long buf1, buf2;
-    
-       if (!db->stopped)
-               return;
-
-       spin_lock_irqsave(&s->lock, flags);
-
-       // reset Buffer 1 and 2 pointers to nextIn and nextIn+fragsize
-       buf1 = virt_to_bus(db->nextIn);
-       buf2 = buf1 + db->fragsize;
-       if (buf2 >= db->dmaaddr + db->dmasize)
-               buf2 -= db->dmasize;
-    
-       outl(buf1, s->io+IT_AC_CAPB1STA);
-       outl(buf2, s->io+IT_AC_CAPB2STA);
-       db->curBufPtr = IT_AC_CAPB1STA;
-
-       // enable capture interrupt
-       imc = inb(s->io+IT_AC_IMC);
-       outb(imc & ~IMC_CCIM, s->io+IT_AC_IMC);
-
-       s->capcc &= ~(CC_CSP | CC_CP | CC_CB2L | CC_CB1L);
-       s->capcc |= CC_CA;
-       outw(s->capcc, s->io+IT_AC_CAPCC);
-    
-       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 it8172_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 = db->nextIn = db->nextOut = NULL;
-       db->mapped = db->ready = 0;
-}
-
-static int prog_dmabuf(struct it8172_state *s, struct dmabuf *db,
-                      unsigned rate, unsigned fmt, unsigned reg)
-{
-       int order;
-       unsigned bytepersec;
-       unsigned bufs;
-       struct page *page, *pend;
-
-       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);
-       }
-
-       db->count = 0;
-       db->nextIn = db->nextOut = db->rawbuf;
-    
-       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 & (CC_DF>>CC_FMT_BIT)) ? 0 : 0x80, bufs);
-    
-#ifdef IT8172_VERBOSE_DEBUG
-       dbg("rate=%d, fragsize=%d, numfrag=%d, dmasize=%d",
-           rate, db->fragsize, db->numfrag, db->dmasize);
-#endif
-
-       // set data length register
-       outw(db->fragsize, s->io+reg+2);
-       db->ready = 1;
-
-       return 0;
-}
-
-static inline int prog_dmabuf_adc(struct it8172_state *s)
-{
-       stop_adc(s);
-       return prog_dmabuf(s, &s->dma_adc, s->adcrate,
-                          (s->capcc & CC_FMT_MASK) >> CC_FMT_BIT,
-                          IT_AC_CAPCC);
-}
-
-static inline int prog_dmabuf_dac(struct it8172_state *s)
-{
-       stop_dac(s);
-       return prog_dmabuf(s, &s->dma_dac, s->dacrate,
-                          (s->pcc & CC_FMT_MASK) >> CC_FMT_BIT,
-                          IT_AC_PCC);
-}
-
-
-/* hold spinlock for the following! */
-
-static irqreturn_t it8172_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-       struct it8172_state *s = (struct it8172_state *)dev_id;
-       struct dmabuf* dac = &s->dma_dac;
-       struct dmabuf* adc = &s->dma_adc;
-       unsigned char isc, vs;
-       unsigned short vol, mute;
-       unsigned long newptr;
-    
-       spin_lock(&s->lock);
-
-       isc = inb(s->io+IT_AC_ISC);
-
-       /* fastpath out, to ease interrupt sharing */
-       if (!(isc & (ISC_VCI | ISC_CCI | ISC_PCI))) {
-               spin_unlock(&s->lock);
-               return IRQ_NONE;
-       }
-    
-       /* clear audio interrupts first */
-       outb(isc | ISC_VCI | ISC_CCI | ISC_PCI, s->io+IT_AC_ISC);
-    
-       /* handle volume button events (ignore if S/PDIF enabled) */
-       if ((isc & ISC_VCI) && s->spdif_volume == -1) {
-               vs = inb(s->io+IT_AC_VS);
-               outb(0, s->io+IT_AC_VS);
-               vol = inw(s->io+IT_AC_PCMOV);
-               mute = vol & PCMOV_PCMOM;
-               vol &= PCMOV_PCMLCG_MASK;
-               if ((vs & VS_VUP) && vol > 0)
-                       vol--;
-               if ((vs & VS_VDP) && vol < 0x1f)
-                       vol++;
-               vol |= (vol << PCMOV_PCMRCG_BIT);
-               if (vs & VS_VMP)
-                       vol |= (mute ^ PCMOV_PCMOM);
-               outw(vol, s->io+IT_AC_PCMOV);
-       }
-    
-       /* update capture pointers */
-       if (isc & ISC_CCI) {
-               if (adc->count > adc->dmasize - adc->fragsize) {
-                       // Overrun. Stop ADC and log the error
-                       stop_adc(s);
-                       adc->error++;
-                       dbg("adc overrun");
-               } else {
-                       newptr = virt_to_bus(adc->nextIn) + 2*adc->fragsize;
-                       if (newptr >= adc->dmaaddr + adc->dmasize)
-                               newptr -= adc->dmasize;
-           
-                       outl(newptr, s->io+adc->curBufPtr);
-                       adc->curBufPtr = (adc->curBufPtr == IT_AC_CAPB1STA) ?
-                               IT_AC_CAPB2STA : IT_AC_CAPB1STA;
-           
-                       adc->nextIn += adc->fragsize;
-                       if (adc->nextIn >= adc->rawbuf + adc->dmasize)
-                               adc->nextIn -= adc->dmasize;
-           
-                       adc->count += adc->fragsize;
-                       adc->total_bytes += adc->fragsize;
-
-                       /* wake up anybody listening */
-                       if (waitqueue_active(&adc->wait))
-                               wake_up_interruptible(&adc->wait);
-               }
-       }
-    
-       /* update playback pointers */
-       if (isc & ISC_PCI) {
-               newptr = virt_to_bus(dac->nextOut) + 2*dac->fragsize;
-               if (newptr >= dac->dmaaddr + dac->dmasize)
-                       newptr -= dac->dmasize;
-       
-               outl(newptr, s->io+dac->curBufPtr);
-               dac->curBufPtr = (dac->curBufPtr == IT_AC_PCB1STA) ?
-                       IT_AC_PCB2STA : IT_AC_PCB1STA;
-       
-               dac->nextOut += dac->fragsize;
-               if (dac->nextOut >= dac->rawbuf + dac->dmasize)
-                       dac->nextOut -= dac->dmasize;
-       
-               dac->count -= dac->fragsize;
-               dac->total_bytes += dac->fragsize;
-
-               /* wake up anybody listening */
-               if (waitqueue_active(&dac->wait))
-                       wake_up_interruptible(&dac->wait);
-       
-               if (dac->count <= 0)
-                       stop_dac(s);
-       }
-    
-       spin_unlock(&s->lock);
-       return IRQ_HANDLED;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int it8172_open_mixdev(struct inode *inode, struct file *file)
-{
-       int minor = iminor(inode);
-       struct list_head *list;
-       struct it8172_state *s;
-
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct it8172_state, devs);
-               if (s->codec.dev_mixer == minor)
-                       break;
-       }
-       file->private_data = s;
-       return nonseekable_open(inode, file);
-}
-
-static int it8172_release_mixdev(struct inode *inode, struct file *file)
-{
-       return 0;
-}
-
-
-static u16
-cvt_ossvol(unsigned int gain)
-{
-       u16 ret;
-    
-       if (gain == 0)
-               return 0;
-    
-       if (gain > 100)
-               gain = 100;
-    
-       ret = (100 - gain + 32) / 4;
-       ret = ret > 31 ? 31 : ret;
-       return ret;
-}
-
-
-static int mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd,
-                       unsigned long arg)
-{
-       struct it8172_state *s = (struct it8172_state *)codec->private_data;
-       unsigned int left, right;
-       unsigned long flags;
-       int val;
-       u16 vol;
-    
-       /*
-        * When we are in S/PDIF mode, we want to disable any analog output so
-        * we filter the master/PCM channel volume ioctls.
-        *
-        * Also filter I2S channel, which AC'97 knows nothing about.
-        */
-
-       switch (cmd) {
-       case SOUND_MIXER_WRITE_VOLUME:
-               // if not in S/PDIF mode, pass to AC'97
-               if (s->spdif_volume == -1)
-                       break;
-               return 0;
-       case SOUND_MIXER_WRITE_PCM:
-               // if not in S/PDIF mode, pass to AC'97
-               if (s->spdif_volume == -1)
-                       break;
-               if (get_user(val, (int *)arg))
-                       return -EFAULT;
-               right = ((val >> 8)  & 0xff);
-               left = (val  & 0xff);
-               if (right > 100)
-                       right = 100;
-               if (left > 100)
-                       left = 100;
-               s->spdif_volume = (right << 8) | left;
-               vol = cvt_ossvol(left);
-               vol |= (cvt_ossvol(right) << PCMOV_PCMRCG_BIT);
-               if (vol == 0)
-                       vol = PCMOV_PCMOM; // mute
-               spin_lock_irqsave(&s->lock, flags);
-               outw(vol, s->io+IT_AC_PCMOV);
-               spin_unlock_irqrestore(&s->lock, flags);
-               return put_user(s->spdif_volume, (int *)arg);
-       case SOUND_MIXER_READ_PCM:
-               // if not in S/PDIF mode, pass to AC'97
-               if (s->spdif_volume == -1)
-                       break;
-               return put_user(s->spdif_volume, (int *)arg);
-       case SOUND_MIXER_WRITE_I2S:
-               if (get_user(val, (int *)arg))
-                       return -EFAULT;
-               right = ((val >> 8)  & 0xff);
-               left = (val  & 0xff);
-               if (right > 100)
-                       right = 100;
-               if (left > 100)
-                       left = 100;
-               s->i2s_volume = (right << 8) | left;
-               vol = cvt_ossvol(left);
-               vol |= (cvt_ossvol(right) << I2SV_I2SRCG_BIT);
-               if (vol == 0)
-                       vol = I2SV_I2SOM; // mute
-               outw(vol, s->io+IT_AC_I2SV);
-               return put_user(s->i2s_volume, (int *)arg);
-       case SOUND_MIXER_READ_I2S:
-               return put_user(s->i2s_volume, (int *)arg);
-       case SOUND_MIXER_WRITE_RECSRC:
-               if (get_user(val, (int *)arg))
-                       return -EFAULT;
-               if (val & SOUND_MASK_I2S) {
-                       s->i2s_recording = 1;
-                       outb(DRSS_I2S, s->io+IT_AC_DRSS);
-                       return 0;
-               } else {
-                       s->i2s_recording = 0;
-                       outb(DRSS_AC97_PRIM, s->io+IT_AC_DRSS);
-                       // now let AC'97 select record source
-                       break;
-               }
-       case SOUND_MIXER_READ_RECSRC:
-               if (s->i2s_recording)
-                       return put_user(SOUND_MASK_I2S, (int *)arg);
-               else
-                       // let AC'97 report recording source
-                       break;
-       }
-
-       return codec->mixer_ioctl(codec, cmd, arg);
-}
-
-static int it8172_ioctl_mixdev(struct inode *inode, struct file *file,
-                              unsigned int cmd, unsigned long arg)
-{
-       struct it8172_state *s = (struct it8172_state *)file->private_data;
-       struct ac97_codec *codec = &s->codec;
-
-       return mixdev_ioctl(codec, cmd, arg);
-}
-
-static /*const*/ struct file_operations it8172_mixer_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .ioctl          = it8172_ioctl_mixdev,
-       .open           = it8172_open_mixdev,
-       .release        = it8172_release_mixdev,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac(struct it8172_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->dacrate;
-               tmo >>= sample_shift[(s->pcc & CC_FMT_MASK) >> CC_FMT_BIT];
-               it8172_delay(tmo);
-       }
-       if (signal_pending(current))
-               return -ERESTARTSYS;
-       return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-
-/*
- * 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;
-       
-       if (bufptr + count > bufend) {
-               int partial = (int)(bufend - bufptr);
-               if (to_user) {
-                       if (copy_to_user(userbuf, bufptr, partial))
-                               return -EFAULT;
-                       if (copy_to_user(userbuf + partial, db->rawbuf,
-                                        count - partial))
-                               return -EFAULT;
-               } else {
-                       if (copy_from_user(bufptr, userbuf, partial))
-                               return -EFAULT;
-                       if (copy_from_user(db->rawbuf,
-                                          userbuf + partial,
-                                          count - partial))
-                               return -EFAULT;
-               }
-       } else {
-               if (to_user) {
-                       if (copy_to_user(userbuf, bufptr, count))
-                               return -EFAULT;
-               } else {
-                       if (copy_from_user(bufptr, userbuf, count))
-                               return -EFAULT;
-               }
-       }
-       
-       return count;
-}
-
-
-static ssize_t it8172_read(struct file *file, char *buffer,
-                          size_t count, loff_t *ppos)
-{
-       struct it8172_state *s = (struct it8172_state *)file->private_data;
-       struct dmabuf *db = &s->dma_adc;
-       ssize_t ret;
-       unsigned long flags;
-       int cnt, remainder, avail;
-
-       if (db->mapped)
-               return -ENXIO;
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       ret = 0;
-
-       while (count > 0) {
-               // wait for samples in capture buffer
-               do {
-                       spin_lock_irqsave(&s->lock, flags);
-                       if (db->stopped)
-                               start_adc(s);
-                       avail = db->count;
-                       spin_unlock_irqrestore(&s->lock, flags);
-                       if (avail <= 0) {
-                               if (file->f_flags & O_NONBLOCK) {
-                                       if (!ret)
-                                               ret = -EAGAIN;
-                                       return ret;
-                               }
-                               interruptible_sleep_on(&db->wait);
-                               if (signal_pending(current)) {
-                                       if (!ret)
-                                               ret = -ERESTARTSYS;
-                                       return ret;
-                               }
-                       }
-               } 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;
-                       return ret;
-               }
-
-               spin_lock_irqsave(&s->lock, flags);
-               db->count -= cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-
-               db->nextOut += cnt;
-               if (db->nextOut >= db->rawbuf + db->dmasize)
-                       db->nextOut -= db->dmasize;     
-
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-       } // while (count > 0)
-
-       /*
-        * See if the dma buffer count after this read call is
-        * aligned on a fragsize boundary. If not, read from
-        * buffer until we reach a boundary, and let's hope this
-        * is just the last remainder of an audio record. If not
-        * it means the user is not reading in fragsize chunks, in
-        * which case it's his/her fault that there are audio gaps
-        * in their record.
-        */
-       spin_lock_irqsave(&s->lock, flags);
-       remainder = db->count % db->fragsize;
-       if (remainder) {
-               db->nextOut += remainder;
-               if (db->nextOut >= db->rawbuf + db->dmasize)
-                       db->nextOut -= db->dmasize;
-               db->count -= remainder;
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-
-       return ret;
-}
-
-static ssize_t it8172_write(struct file *file, const char *buffer,
-                           size_t count, loff_t *ppos)
-{
-       struct it8172_state *s = (struct it8172_state *)file->private_data;
-       struct dmabuf *db = &s->dma_dac;
-       ssize_t ret;
-       unsigned long flags;
-       int cnt, remainder, avail;
-
-       if (db->mapped)
-               return -ENXIO;
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       ret = 0;
-    
-       while (count > 0) {
-               // wait for space in playback buffer
-               do {
-                       spin_lock_irqsave(&s->lock, flags);
-                       avail = db->dmasize - db->count;
-                       spin_unlock_irqrestore(&s->lock, flags);
-                       if (avail <= 0) {
-                               if (file->f_flags & O_NONBLOCK) {
-                                       if (!ret)
-                                               ret = -EAGAIN;
-                                       return ret;
-                               }
-                               interruptible_sleep_on(&db->wait);
-                               if (signal_pending(current)) {
-                                       if (!ret)
-                                               ret = -ERESTARTSYS;
-                                       return ret;
-                               }
-                       }
-               } while (avail <= 0);
-       
-               // copy to nextIn
-               if ((cnt = copy_dmabuf_user(db, (char*)buffer,
-                                           count > avail ?
-                                           avail : count, 0)) < 0) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       return ret;
-               }
-
-               spin_lock_irqsave(&s->lock, flags);
-               db->count += cnt;
-               if (db->stopped)
-                       start_dac(s);
-               spin_unlock_irqrestore(&s->lock, flags);
-       
-               db->nextIn += cnt;
-               if (db->nextIn >= db->rawbuf + db->dmasize)
-                       db->nextIn -= db->dmasize;
-       
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-       } // while (count > 0)
-       
-       /*
-        * See if the dma buffer count after this write call is
-        * aligned on a fragsize boundary. If not, fill buffer
-        * with silence to the next boundary, and let's hope this
-        * is just the last remainder of an audio playback. If not
-        * it means the user is not sending us fragsize chunks, in
-        * which case it's his/her fault that there are audio gaps
-        * in their playback.
-        */
-       spin_lock_irqsave(&s->lock, flags);
-       remainder = db->count % db->fragsize;
-       if (remainder) {
-               int fill_cnt = db->fragsize - remainder;
-               memset(db->nextIn, 0, fill_cnt);
-               db->nextIn += fill_cnt;
-               if (db->nextIn >= db->rawbuf + db->dmasize)
-                       db->nextIn -= db->dmasize;
-               db->count += fill_cnt;
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-
-       return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int it8172_poll(struct file *file,
-                               struct poll_table_struct *wait)
-{
-       struct it8172_state *s = (struct it8172_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.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 it8172_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       struct it8172_state *s = (struct it8172_state *)file->private_data;
-       struct dmabuf *db;
-       unsigned long size;
-
-       lock_kernel();
-       if (vma->vm_flags & VM_WRITE)
-               db = &s->dma_dac;
-       else if (vma->vm_flags & VM_READ)
-               db = &s->dma_adc;
-       else {
-               unlock_kernel();
-               return -EINVAL;
-       }
-       if (vma->vm_pgoff != 0) {
-               unlock_kernel();
-               return -EINVAL;
-       }
-       size = vma->vm_end - vma->vm_start;
-       if (size > (PAGE_SIZE << db->buforder)) {
-               unlock_kernel();
-               return -EINVAL;
-       }
-       if (remap_pfn_range(vma, vma->vm_start,
-                            virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
-                            size, vma->vm_page_prot)) {
-               unlock_kernel();
-               return -EAGAIN;
-       }
-       db->mapped = 1;
-       unlock_kernel();
-       return 0;
-}
-
-
-#ifdef IT8172_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    
-
-static int it8172_ioctl(struct inode *inode, struct file *file,
-                       unsigned int cmd, unsigned long arg)
-{
-       struct it8172_state *s = (struct it8172_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 IT8172_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%08x",
-                   ioctl_str[count].str, (unsigned int)arg);
-       else
-               dbg("ioctl unknown, 0x%x", cmd);
-#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->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->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 ((ret = prog_dmabuf_adc(s)))
-                                       return ret;
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               set_dac_rate(s, val);
-                               if ((ret = prog_dmabuf_dac(s)))
-                                       return ret;
-                       }
-               }
-               return put_user((file->f_mode & FMODE_READ) ?
-                               s->adcrate : s->dacrate, (int *)arg);
-
-       case SNDCTL_DSP_STEREO:
-               if (get_user(val, (int *)arg))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       if (val)
-                               s->capcc |= CC_SM;
-                       else
-                               s->capcc &= ~CC_SM;
-                       outw(s->capcc, s->io+IT_AC_CAPCC);
-                       if ((ret = prog_dmabuf_adc(s)))
-                               return ret;
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       if (val)
-                               s->pcc |= CC_SM;
-                       else
-                               s->pcc &= ~CC_SM;
-                       outw(s->pcc, s->io+IT_AC_PCC);
-                       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) {
-                               stop_adc(s);
-                               if (val >= 2) {
-                                       val = 2;
-                                       s->capcc |= CC_SM;
-                               }
-                               else
-                                       s->capcc &= ~CC_SM;
-                               outw(s->capcc, s->io+IT_AC_CAPCC);
-                               if ((ret = prog_dmabuf_adc(s)))
-                                       return ret;
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               switch (val) {
-                               case 1:
-                                       s->pcc &= ~CC_SM;
-                                       break;
-                               case 2:
-                                       s->pcc |= CC_SM;
-                                       break;
-                               default:
-                                       // FIX! support multichannel???
-                                       val = 2;
-                                       s->pcc |= CC_SM;
-                                       break;
-                               }
-                               outw(s->pcc, s->io+IT_AC_PCC);
-                               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->capcc |= CC_DF;
-                               else {
-                                       val = AFMT_U8;
-                                       s->capcc &= ~CC_DF;
-                               }
-                               outw(s->capcc, s->io+IT_AC_CAPCC);
-                               if ((ret = prog_dmabuf_adc(s)))
-                                       return ret;
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               if (val == AFMT_S16_LE)
-                                       s->pcc |= CC_DF;
-                               else {
-                                       val = AFMT_U8;
-                                       s->pcc &= ~CC_DF;
-                               }
-                               outw(s->pcc, s->io+IT_AC_PCC);
-                               if ((ret = prog_dmabuf_dac(s)))
-                                       return ret;
-                       }
-               } else {
-                       if (file->f_mode & FMODE_READ)
-                               val = (s->capcc & CC_DF) ?
-                                       AFMT_S16_LE : AFMT_U8;
-                       else
-                               val = (s->pcc & CC_DF) ?
-                                       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;
-               if (!s->dma_dac.stopped)
-                       count -= (s->dma_dac.fragsize -
-                                 inw(s->io+IT_AC_PCDL));
-               spin_unlock_irqrestore(&s->lock, flags);
-               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;      
-               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;
-               if (!s->dma_adc.stopped)
-                       count += (s->dma_adc.fragsize -
-                                 inw(s->io+IT_AC_CAPCDL));
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count < 0)
-                       count = 0;
-               abinfo.bytes = count;
-               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;
-               if (!s->dma_dac.stopped)
-                       count -= (s->dma_dac.fragsize -
-                                 inw(s->io+IT_AC_PCDL));
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count < 0)
-                       count = 0;
-               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 = s->dma_adc.fragsize - inw(s->io+IT_AC_CAPCDL);
-                       count += diff;
-                       cinfo.bytes += diff;
-                       cinfo.ptr = inl(s->io+s->dma_adc.curBufPtr) -
-                               s->dma_adc.dmaaddr;
-               } else
-                       cinfo.ptr = virt_to_bus(s->dma_adc.nextIn) -
-                               s->dma_adc.dmaaddr;
-               if (s->dma_adc.mapped)
-                       s->dma_adc.count &= s->dma_adc.fragsize-1;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count < 0)
-                       count = 0;
-               cinfo.blocks = count >> s->dma_adc.fragshift;
-               if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 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 = s->dma_dac.fragsize - inw(s->io+IT_AC_CAPCDL);
-                       count -= diff;
-                       cinfo.bytes += diff;
-                       cinfo.ptr = inl(s->io+s->dma_dac.curBufPtr) -
-                               s->dma_dac.dmaaddr;
-               } else
-                       cinfo.ptr = virt_to_bus(s->dma_dac.nextOut) -
-                               s->dma_dac.dmaaddr;
-               if (s->dma_dac.mapped)
-                       s->dma_dac.count &= s->dma_dac.fragsize-1;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count < 0)
-                       count = 0;
-               cinfo.blocks = count >> s->dma_dac.fragshift;
-               if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 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->adcrate : s->dacrate, (int *)arg);
-
-       case SOUND_PCM_READ_CHANNELS:
-               if (file->f_mode & FMODE_READ)
-                       return put_user((s->capcc & CC_SM) ? 2 : 1,
-                                       (int *)arg);
-               else
-                       return put_user((s->pcc & CC_SM) ? 2 : 1,
-                                       (int *)arg);
-           
-       case SOUND_PCM_READ_BITS:
-               if (file->f_mode & FMODE_READ)
-                       return put_user((s->capcc & CC_DF) ? 16 : 8,
-                                       (int *)arg);
-               else
-                       return put_user((s->pcc & CC_DF) ? 16 : 8,
-                                       (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 it8172_open(struct inode *inode, struct file *file)
-{
-       int minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       struct list_head *list;
-       struct it8172_state *s;
-       int ret;
-    
-#ifdef IT8172_VERBOSE_DEBUG
-       if (file->f_flags & O_NONBLOCK)
-               dbg("%s: non-blocking", __FUNCTION__);
-       else
-               dbg("%s: blocking", __FUNCTION__);
-#endif
-       
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct it8172_state, devs);
-               if (!((s->dev_audio ^ minor) & ~0xf))
-                       break;
-       }
-       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 (file->f_mode & FMODE_READ) {
-               s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
-                       s->dma_adc.subdivision = s->dma_adc.total_bytes = 0;
-               s->capcc &= ~(CC_SM | CC_DF);
-               set_adc_rate(s, 8000);
-               if ((minor & 0xf) == SND_DEV_DSP16)
-                       s->capcc |= CC_DF;
-               outw(s->capcc, s->io+IT_AC_CAPCC);
-               if ((ret = prog_dmabuf_adc(s))) {
-                       spin_unlock_irqrestore(&s->lock, flags);
-                       return ret;
-               }
-       }
-       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->pcc &= ~(CC_SM | CC_DF);
-               set_dac_rate(s, 8000);
-               if ((minor & 0xf) == SND_DEV_DSP16)
-                       s->pcc |= CC_DF;
-               outw(s->pcc, s->io+IT_AC_PCC);
-               if ((ret = prog_dmabuf_dac(s))) {
-                       spin_unlock_irqrestore(&s->lock, flags);
-                       return ret;
-               }
-       }
-    
-       spin_unlock_irqrestore(&s->lock, flags);
-
-       s->open_mode |= (file->f_mode & (FMODE_READ | FMODE_WRITE));
-       mutex_unlock(&s->open_mutex);
-       return nonseekable_open(inode, file);
-}
-
-static int it8172_release(struct inode *inode, struct file *file)
-{
-       struct it8172_state *s = (struct it8172_state *)file->private_data;
-
-#ifdef IT8172_VERBOSE_DEBUG
-       dbg("%s", __FUNCTION__);
-#endif
-       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));
-       mutex_unlock(&s->open_mutex);
-       wake_up(&s->open_wait);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const*/ struct file_operations it8172_audio_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .read           = it8172_read,
-       .write          = it8172_write,
-       .poll           = it8172_poll,
-       .ioctl          = it8172_ioctl,
-       .mmap           = it8172_mmap,
-       .open           = it8172_open,
-       .release        = it8172_release,
-};
-
-
-/* --------------------------------------------------------------------- */
-
-
-/* --------------------------------------------------------------------- */
-
-/*
- * for debugging purposes, we'll create a proc device that dumps the
- * CODEC chipstate
- */
-
-#ifdef IT8172_DEBUG
-static int proc_it8172_dump (char *buf, char **start, off_t fpos,
-                            int length, int *eof, void *data)
-{
-       struct it8172_state *s;
-       int cnt, len = 0;
-
-       if (list_empty(&devs))
-               return 0;
-       s = list_entry(devs.next, struct it8172_state, devs);
-
-       /* print out header */
-       len += sprintf(buf + len, "\n\t\tIT8172 Audio Debug\n\n");
-
-       // print out digital controller state
-       len += sprintf (buf + len, "IT8172 Audio Controller registers\n");
-       len += sprintf (buf + len, "---------------------------------\n");
-       cnt=0;
-       while (cnt < 0x72) {
-               if (cnt == IT_AC_PCB1STA || cnt == IT_AC_PCB2STA ||
-                   cnt == IT_AC_CAPB1STA || cnt == IT_AC_CAPB2STA ||
-                   cnt == IT_AC_PFDP) {
-                       len+= sprintf (buf + len, "reg %02x = %08x\n",
-                                      cnt, inl(s->io+cnt));
-                       cnt += 4;
-               } else {
-                       len+= sprintf (buf + len, "reg %02x = %04x\n",
-                                      cnt, inw(s->io+cnt));
-                       cnt += 2;
-               }
-       }
-    
-       /* print out CODEC state */
-       len += sprintf (buf + len, "\nAC97 CODEC registers\n");
-       len += sprintf (buf + len, "----------------------\n");
-       for (cnt=0; cnt <= 0x7e; cnt = 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 /* IT8172_DEBUG */
-
-/* --------------------------------------------------------------------- */
-
-/* maximum number of devices; only used for command line params */
-#define NR_DEVICE 5
-
-static int spdif[NR_DEVICE];
-static int i2s_fmt[NR_DEVICE];
-
-static unsigned int devindex;
-
-module_param_array(spdif, int, NULL, 0);
-MODULE_PARM_DESC(spdif, "if 1 the S/PDIF digital output is enabled");
-module_param_array(i2s_fmt, int, NULL, 0);
-MODULE_PARM_DESC(i2s_fmt, "the format of I2S");
-
-MODULE_AUTHOR("Monta Vista Software, stevel@mvista.com");
-MODULE_DESCRIPTION("IT8172 Audio Driver");
-
-/* --------------------------------------------------------------------- */
-
-static int __devinit it8172_probe(struct pci_dev *pcidev,
-                                 const struct pci_device_id *pciid)
-{
-       struct it8172_state *s;
-       int i, val;
-       unsigned short pcisr, vol;
-       unsigned char legacy, imc;
-       char proc_str[80];
-    
-       if (pcidev->irq == 0) 
-               return -1;
-
-       if (!(s = kmalloc(sizeof(struct it8172_state), GFP_KERNEL))) {
-               err("alloc of device struct failed");
-               return -1;
-       }
-       
-       memset(s, 0, sizeof(struct it8172_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->dev = pcidev;
-       s->io = pci_resource_start(pcidev, 0);
-       s->irq = pcidev->irq;
-       s->vendor = pcidev->vendor;
-       s->device = pcidev->device;
-       pci_read_config_byte(pcidev, PCI_REVISION_ID, &s->rev);
-       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_region(s->io, pci_resource_len(pcidev,0),
-                           IT8172_MODULE_NAME)) {
-               err("io ports %#lx->%#lx in use",
-                   s->io, s->io + pci_resource_len(pcidev,0)-1);
-               goto err_region;
-       }
-       if (request_irq(s->irq, it8172_interrupt, IRQF_DISABLED,
-                       IT8172_MODULE_NAME, s)) {
-               err("irq %u in use", s->irq);
-               goto err_irq;
-       }
-
-       info("IO at %#lx, IRQ %d", s->io, s->irq);
-
-       /* register devices */
-       if ((s->dev_audio = register_sound_dsp(&it8172_audio_fops, -1)) < 0)
-               goto err_dev1;
-       if ((s->codec.dev_mixer =
-            register_sound_mixer(&it8172_mixer_fops, -1)) < 0)
-               goto err_dev2;
-
-#ifdef IT8172_DEBUG
-       /* initialize the debug proc device */
-       s->ps = create_proc_read_entry(IT8172_MODULE_NAME, 0, NULL,
-                                      proc_it8172_dump, NULL);
-#endif /* IT8172_DEBUG */
-       
-       /*
-        * Reset the Audio device using the IT8172 PCI Reset register. This
-        * creates an audible double click on a speaker connected to Line-out.
-        */
-       IT_IO_READ16(IT_PM_PCISR, pcisr);
-       pcisr |= IT_PM_PCISR_ACSR;
-       IT_IO_WRITE16(IT_PM_PCISR, pcisr);
-       /* wait up to 100msec for reset to complete */
-       for (i=0; pcisr & IT_PM_PCISR_ACSR; i++) {
-               it8172_delay(10);
-               if (i == 10)
-                       break;
-               IT_IO_READ16(IT_PM_PCISR, pcisr);
-       }
-       if (i == 10) {
-               err("chip reset timeout!");
-               goto err_dev3;
-       }
-    
-       /* enable pci io and bus mastering */
-       if (pci_enable_device(pcidev))
-               goto err_dev3;
-       pci_set_master(pcidev);
-
-       /* get out of legacy mode */
-       pci_read_config_byte (pcidev, 0x40, &legacy);
-       pci_write_config_byte (pcidev, 0x40, legacy & ~1);
-    
-       s->spdif_volume = -1;
-       /* check to see if s/pdif mode is being requested */
-       if (spdif[devindex]) {
-               info("enabling S/PDIF output");
-               s->spdif_volume = 0;
-               outb(GC_SOE, s->io+IT_AC_GC);
-       } else {
-               info("disabling S/PDIF output");
-               outb(0, s->io+IT_AC_GC);
-       }
-    
-       /* check to see if I2S format requested */
-       if (i2s_fmt[devindex]) {
-               info("setting I2S format to 0x%02x", i2s_fmt[devindex]);
-               outb(i2s_fmt[devindex], s->io+IT_AC_I2SMC);
-       } else {
-               outb(I2SMC_I2SF_I2S, s->io+IT_AC_I2SMC);
-       }
-
-       /* cold reset the AC97 */
-       outw(CODECC_CR, s->io+IT_AC_CODECC);
-       udelay(1000);
-       outw(0, s->io+IT_AC_CODECC);
-       /* need to delay around 500msec(bleech) to give
-          some CODECs enough time to wakeup */
-       it8172_delay(500);
-    
-       /* AC97 warm reset to start the bitclk */
-       outw(CODECC_WR, s->io+IT_AC_CODECC);
-       udelay(1000);
-       outw(0, s->io+IT_AC_CODECC);
-    
-       /* codec init */
-       if (!ac97_probe_codec(&s->codec))
-               goto err_dev3;
-
-       /* add I2S as allowable recording source */
-       s->codec.record_sources |= SOUND_MASK_I2S;
-       
-       /* Enable Volume button interrupts */
-       imc = inb(s->io+IT_AC_IMC);
-       outb(imc & ~IMC_VCIM, s->io+IT_AC_IMC);
-
-       /* Un-mute PCM and FM out on the controller */
-       vol = inw(s->io+IT_AC_PCMOV);
-       outw(vol & ~PCMOV_PCMOM, s->io+IT_AC_PCMOV);
-       vol = inw(s->io+IT_AC_FMOV);
-       outw(vol & ~FMOV_FMOM, s->io+IT_AC_FMOV);
-    
-       /* set channel defaults to 8-bit, mono, 8 Khz */
-       s->pcc = 0;
-       s->capcc = 0;
-       set_dac_rate(s, 8000);
-       set_adc_rate(s, 8000);
-
-       /* set mic to be the recording source */
-       val = SOUND_MASK_MIC;
-       mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_RECSRC,
-                    (unsigned long)&val);
-
-       /* mute AC'97 master and PCM when in S/PDIF mode */
-       if (s->spdif_volume != -1) {
-               val = 0x0000;
-               s->codec.mixer_ioctl(&s->codec, SOUND_MIXER_WRITE_VOLUME,
-                                    (unsigned long)&val);
-               s->codec.mixer_ioctl(&s->codec, SOUND_MIXER_WRITE_PCM,
-                                    (unsigned long)&val);
-       }
-    
-#ifdef IT8172_DEBUG
-       sprintf(proc_str, "driver/%s/%d/ac97", IT8172_MODULE_NAME,
-               s->codec.id);
-       s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
-                                            ac97_read_proc, &s->codec);
-#endif
-    
-       /* store it in the driver field */
-       pci_set_drvdata(pcidev, s);
-       pcidev->dma_mask = 0xffffffff;
-       /* put it into driver list */
-       list_add_tail(&s->devs, &devs);
-       /* increment devindex */
-       if (devindex < NR_DEVICE-1)
-               devindex++;
-       return 0;
-
- err_dev3:
-       unregister_sound_mixer(s->codec.dev_mixer);
- err_dev2:
-       unregister_sound_dsp(s->dev_audio);
- err_dev1:
-       err("cannot register misc device");
-       free_irq(s->irq, s);
- err_irq:
-       release_region(s->io, pci_resource_len(pcidev,0));
- err_region:
-       kfree(s);
-       return -1;
-}
-
-static void __devexit it8172_remove(struct pci_dev *dev)
-{
-       struct it8172_state *s = pci_get_drvdata(dev);
-
-       if (!s)
-               return;
-       list_del(&s->devs);
-#ifdef IT8172_DEBUG
-       if (s->ps)
-               remove_proc_entry(IT8172_MODULE_NAME, NULL);
-#endif /* IT8172_DEBUG */
-       synchronize_irq(s->irq);
-       free_irq(s->irq, s);
-       release_region(s->io, pci_resource_len(dev,0));
-       unregister_sound_dsp(s->dev_audio);
-       unregister_sound_mixer(s->codec.dev_mixer);
-       kfree(s);
-       pci_set_drvdata(dev, NULL);
-}
-
-
-
-static struct pci_device_id id_table[] = {
-       { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_IT8172G_AUDIO, PCI_ANY_ID,
-         PCI_ANY_ID, 0, 0 },
-       { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, id_table);
-
-static struct pci_driver it8172_driver = {
-       .name = IT8172_MODULE_NAME,
-       .id_table = id_table,
-       .probe = it8172_probe,
-       .remove = __devexit_p(it8172_remove)
-};
-
-static int __init init_it8172(void)
-{
-       info("version v0.5 time " __TIME__ " " __DATE__);
-       return pci_register_driver(&it8172_driver);
-}
-
-static void __exit cleanup_it8172(void)
-{
-       info("unloading");
-       pci_unregister_driver(&it8172_driver);
-}
-
-module_init(init_it8172);
-module_exit(cleanup_it8172);
-
-/* --------------------------------------------------------------------- */
-
-#ifndef MODULE
-
-/* format is: it8172=[spdif],[i2s:<I2S format>] */
-
-static int __init it8172_setup(char *options)
-{
-       char* this_opt;
-       static unsigned __initdata nr_dev = 0;
-
-       if (nr_dev >= NR_DEVICE)
-               return 0;
-
-       if (!options || !*options)
-               return 0;
-
-       while (this_opt = strsep(&options, ",")) {
-               if (!*this_opt)
-                       continue;
-               if (!strncmp(this_opt, "spdif", 5)) {
-                       spdif[nr_dev] = 1;
-               } else if (!strncmp(this_opt, "i2s:", 4)) {
-                       if (!strncmp(this_opt+4, "dac", 3))
-                               i2s_fmt[nr_dev] = I2SMC_I2SF_DAC;
-                       else if (!strncmp(this_opt+4, "adc", 3))
-                               i2s_fmt[nr_dev] = I2SMC_I2SF_ADC;
-                       else if (!strncmp(this_opt+4, "i2s", 3))
-                               i2s_fmt[nr_dev] = I2SMC_I2SF_I2S;
-               }
-       }
-
-       nr_dev++;
-       return 1;
-}
-
-__setup("it8172=", it8172_setup);
-
-#endif /* MODULE */
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 ce79cd82478afac2d1eaa746a2b115e649afbcb1..147c816a1f2293914ba3b902dd987180ecb40cae 100644 (file)
@@ -1862,7 +1862,7 @@ trident_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos
        unsigned swptr;
        int cnt;
 
-       pr_debug("trident: trident_read called, count = %d\n", count);
+       pr_debug("trident: trident_read called, count = %zd\n", count);
 
        VALIDATE_STATE(state);
 
@@ -1978,7 +1978,7 @@ trident_write(struct file *file, const char __user *buffer, size_t count, loff_t
        unsigned int copy_count;
        int lret; /* for lock_set_fmt */
 
-       pr_debug("trident: trident_write called, count = %d\n", count);
+       pr_debug("trident: trident_write called, count = %zd\n", count);
 
        VALIDATE_STATE(state);
 
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
  */